NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #3362 most downloaded on npm
The lightest signal library.
Last release 4 months ago
14 May 2026
Release timing varies
gaps range from 8 days to 5 months
Rarely documented
notes for 3 of the last 60 stable releases
5 versions withdrawn
withdrawn after publishing
2 years old
81 releases · first in 2024
One column per month.
Nothing published for this version
Effect cleanup functions — Effects can now return a cleanup function that runs before each re-execution and on disposal (#113) `ts effect(() => { cons
effect(() => {
const handler = () => { /* ... */ };
document.addEventListener('click', handler);
return () => document.removeEventListener('click', handler);
});
checkDirty resilient to graph mutations during update (#109, #110)effectScope not participating in propagation (#111)If you implement custom effect/computed execution using createReactiveSystem, you must wrap the execution body with ++runDepth / --runDepth. This counter drives the innerWrite parameter to propagate, which provides two directions of protection:
RecursedCheck) won't be re-triggered by its own writeRecursed during inner writes, which acts as a bookmark for the propagation state machine. Without this mark, subsequent top-level writes will see stale flags and skip propagation through computed chains — this is the bug fixed in #112Integrate reactive-framework-test-suite — a cross-framework conformance suite with 180 test cases across 13 reactive libraries. alien-signals is the only framework that passes all 180 tests (#114).
| Framework | Pass / 180 |
|---|---|
| alien-signals | 180 |
| @preact/signals-core | 178 |
| @vue/reactivity | 172 |
| anod | 166 |
| tansu | 163 |
| @solidjs/signals | 161 |
| solid-js | 154 |
| mobx | 148 |
| signal-polyfill (TC39) | 145 |
| @angular/core | 141 |
| svelte | 131 |
| S.js | 130 |
| @reactively/core | 114 |
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Version 2.0 rethinks and optimizes the reactive system model, with minimal impact on users who only use the surface APIs. If you extend or deeply util
Version 2.0 rethinks and optimizes the reactive system model, with minimal impact on users who only use the surface APIs. If you extend or deeply utilize alien-signals, please pay attention to the "Reactive Model Refactor" section.
getCurrentSub, setCurrentSub, getCurrentScope, setCurrentScopeIn v1, assigning a value to a signal immediately propagated the
Dirtyflag, causing some computed values to be unnecessarily re-evaluated.
// v1
const src = signal(10);
const double = computed(() => src() * 2);
double(); // -> 20
src(999); // double.flags -> Dirty
src(10); // no effect
double(); // -> 20 (recomputed unnecessarily)
In v2, assigning a value to a signal only propagates the
Pendingflag, reducing unnecessary recomputation. Actual evaluation occurs during the next read.
// v2
const src = signal(10);
const double = computed(() => src() * 2);
double(); // -> 20
src(999); // src.flags -> Dirty, double.flags -> Pending
src(10); // no effect
double(); // Checks src state -> unchanged, no recomputation needed
In v2, recursive cleanup is achieved through a parent-child structure:
const scope1 = effectScope(() => {
const scope2 = effectScope(() => {
effect(() => ...);
computed(() => ...);
});
});
scope1();
Calling scope1() automatically cleans up its child scope scope2.
To make scope2 independent of scope1, temporarily set activeScope = undefined manually:
const scope1 = effectScope(() => {
const prev = setCurrentScope(undefined);
const scope2 = effectScope(() => {
effect(() => ...);
computed(() => ...);
});
setCurrentScope(prev);
});
Subscriber and Dependency into ReactiveNodeunwatched(dep) when all subscribers are lost, without recursively clearing subsequent subscriberspropagate now only propagates Pending; to immediately mark Dirty, call propagate + shallowPropagate after assignmentEffectFlags and ReactiveFlags; removed unused flagsnotifyEffect → notifyupdateComputed → updateunwatched option for custom handling when all subscribers are lostprocessEffectNotifications, processComputedUpdate, processPendingInnerEffects, updateDirtyFlagunlink, checkDirtyFor performance differences, please refer to js-reactivity-benchmark.
<table> <tbody> <tr> <td align="center" valign="middle" colspan="6"> <b>Special Sponsor</b> </td> </tr> <tr> <td align="center" valign="middle" colspan="6"> <br> <a href="https://voidzero.dev/"> <img src="https://raw.githubusercontent.com/johnsoncodehk/sponsors/master/logos/VoidZero.svg" height="60" /> </a> <h3>Next Generation Tooling</h3> </td> </tr> <tr> <td align="center" valign="middle" colspan="6"> <b>Platinum Sponsors</b> </td> </tr> <tr> <td align="center" valign="middle" width="50%" colspan="3"> <a href="https://vuejs.org/"> <img src="https://raw.githubusercontent.com/johnsoncodehk/sponsors/master/logos/Vue.svg" height="80" /> </a> <p>An approachable, performant and versatile framework for building web user interfaces.</p> </td> <td align="center" valign="middle" colspan="3"> <a href="https://stackblitz.com/"> <img src="https://raw.githubusercontent.com/johnsoncodehk/sponsors/master/logos/StackBlitz.svg" width="240" /> </a> <p>Stay in the flow with instant dev experiences.<br>No more hours stashing/pulling/installing locally</p> <p><b> — just click, and start coding.</b></p> </td> <tr> <td align="center" valign="middle" colspan="3"> <a href="https://www.jetbrains.com/"> <img src="https://raw.githubusercontent.com/johnsoncodehk/sponsors/master/logos/JetBrains.svg" width="80" /> </a> <p>Essential tools for software developers and teams.</p> </td> <td align="center" valign="middle" colspan="3"> </td> </tr> <tr> <td align="center" valign="middle" colspan="6"> <b>Silver Sponsors</b> </td> </tr> <tr> <td align="center" valign="middle" width="33.3%" colspan="2"> <a href="https://www.prefect.io/"><img src="https://raw.githubusercontent.com/johnsoncodehk/sponsors/master/logos/Prefect.svg" width="200" /></a> </td> <td align="center" valign="middle" width="33.3%" colspan="2"> <a href="https://antfu.me/"><img src="https://avatars.githubusercontent.com/u/11247099?v=4" height="80" /></a> </td> <td align="center" valign="middle" width="33.3%" colspan="2"> </td> </tr> </tbody> </table>
<p align="center"> <a href="https://github.com/sponsors/johnsoncodehk">You?</a> </p>
<p align="center"> <a href="https://cdn.jsdelivr.net/gh/johnsoncodehk/sponsors/sponsors.svg"> <img src="https://cdn.jsdelivr.net/gh/johnsoncodehk/sponsors/sponsors.png"/> </a> </p>
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
The core algorithm is now decoupled from the public API, and you can redesign your surface API using the alien-signals algorithm.
createReactiveSystem() APIThe core algorithm is now decoupled from the public API, and you can redesign your surface API using the alien-signals algorithm.
(The following example is based on https://github.com/proposal-signals/signal-polyfill/pull/44)
const system = createReactiveSystem({
updateComputed(computed: Computed) {
return computed.update();
},
notifyEffect(watcher: subtle.Watcher) {
if (watcher.flags & alien.SubscriberFlags.Dirty) {
watcher.run();
return true;
}
return false;
},
});
The class-based API design can minimize memory usage, but at the same time I think the get() and set() methods of class signal are also significantly worse in DX.
Since the core algorithm is now decoupled from the surface API, we decided to stop caring about scalability and memory footprint and switch to a function-based API to ensure proper DX by default.
For the latest API usage, please refer to the readme: https://github.com/stackblitz/alien-signals#usage
With the 1.0 refactor changes, we have again seen performance improvements in our internal benchmark scripts in alien-signals.
Please note that this improvement is only theoretical since the --jitless flag is disabled in the alien-signals bench script, but it is a good thing anyway. :)
<img width="619" alt="image" src="https://github.com/user-attachments/assets/5bd6c20e-d51f-409c-b4b7-50aa2a10cc5d" />
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →