signal()
Writable reactive state. Read by calling it, write with set or update.
const count = signal(0)
count()
count.set(1)
count.update((v) => v + 1)
Reactive primitives for JavaScript.
Note: Demo requires build step first (imports from dist/).
Writable reactive state. Read by calling it, write with set or update.
const count = signal(0)
count()
count.set(1)
count.update((v) => v + 1)
Derived state. Tracks dependencies automatically and recomputes lazily when inputs change.
const price = signal(25)
const qty = signal(3)
const total = computed(() => price() * qty())
total()
Derived but writable. Resets to the source value whenever the source changes.
const base = signal(100)
const draft = linkedSignal(() => base())
draft.set(125)
base.set(200)
draft()
Draft follows base but stays writable. Changing base resets the draft.
Fetches pokeapi.co/api/v2/pokemon/:id. Stale requests are aborted automatically.
Mirrors a source signal with a delay. Output only updates once the source has been stable for ms milliseconds. Useful for search inputs, resize handlers, and rate-limiting reactive computations.
const query = signal('')
const debounced = debounceSignal(query, 300)
effect(() => {
// fires at most once every 300ms
console.log('search:', debounced())
})
query.set('h')
query.set('he')
query.set('hel')
query.set('hell')
query.set('hello')
// effect fires once with 'hello'
Type in the search box. Each keystroke updates the raw signal immediately, but the debounced signal only fires after you stop typing for the configured delay.
Queue optimistic updates immediately, then commit or roll back when the request settles.
| API | What It Solves | Use It When |
|---|---|---|
signal(initial, options?) |
Writable reactive state with set, update, mutate, asReadonly(), and optional custom equality. |
You own the source of truth and need explicit writes. |
computed(fn) |
Lazily derived state that tracks dependencies automatically. | You need a value derived from other signals without storing duplicate state. |
effect(fn, options?) |
Reactive side effects with cleanup and optional rerun scheduling. | You need to sync with DOM, storage, timers, or network side effects. |
batch(fn) |
Coalesces multiple writes so dependents rerun once. | You update several related signals in one logical transaction. |
untracked(fn) |
Reads signals without subscribing the current computation. | You need the current value for branching or logging without capturing a dependency. |
linkedSignal(...) |
Writable derived state that resets when its source changes. | You need editable draft state that should still follow a parent signal. |
resource(...) |
Reactive async loading with cancellation and stale-value retention. | You fetch async data driven by another signal. |
optimistic(source) |
Projects local intent on top of settled state, then commits or rolls back. | You need optimistic UI without mutating base state early. |
debounceSignal(source, ms) |
Read-only signal that delays propagation until the source is stable for ms. |
You need to rate-limit reactive updates (search input, resize, scroll). |
const serverLikes = signal(42)
const optimisticLikes = optimistic(serverLikes)
async function likePost() {
const tx = optimisticLikes.apply((v) => v + 1)
try {
const result = await api.likePost()
tx.commit(result.likes)
} catch {
tx.rollback()
}
}