Reactive signals with computed values, effects, and batching. Zero deps. TypeScript-first.
npm install @corvid-agent/signalimport { signal, computed, effect, batch } from "@corvid-agent/signal";
// Writable signal
const count = signal(0);
console.log(count.value); // 0
// Computed (derived) signal
const doubled = computed(() => count.value * 2);
console.log(doubled.value); // 0
// Effect — runs immediately and re-runs when dependencies change
const dispose = effect(() => {
console.log("doubled is", doubled.value);
});
// logs: "doubled is 0"
count.value = 5;
// logs: "doubled is 10"
// Batch — defer effects until all updates are applied
batch(() => {
count.value = 1;
count.value = 2;
});
// logs once: "doubled is 4"
// Stop listening
dispose();Create a writable reactive signal.
.value— get/set the current value (tracks dependencies on read).peek()— read without tracking
Options:
equals— custom equality function (default:Object.is)
Create a read-only derived signal. Re-evaluates lazily when dependencies change.
.value— get the derived value (tracks dependencies).peek()— read without tracking
Options:
equals— custom equality function (default:Object.is)
Create a side effect that runs whenever its dependencies change. Runs immediately on creation.
The effect function may return a cleanup function, which is called before each re-run and on disposal.
Returns a Dispose function to stop the effect.
Batch multiple signal updates. Effects only run once after all updates are applied. Supports nesting.
Run a function without tracking signal reads as dependencies.
- Automatic dependency tracking — no manual subscriptions
- Lazy evaluation — computeds only recompute when read
- Batching — group updates to minimize effect re-runs
- Cleanup — effects support cleanup functions
- Circular dependency detection — throws on circular computeds
- Dynamic dependencies — tracks only what's actually read each run
- Custom equality — control when updates propagate
- Zero dependencies
MIT