Signals

Reactive primitives for JavaScript.

Note: Demo requires build step first (imports from dist/).

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)

computed()

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()

linkedSignal()

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()

linkedSignal() · Live

Draft follows base but stays writable. Changing base resets the draft.

              
            

resource() · Live HTTP

Fetches pokeapi.co/api/v2/pokemon/:id. Stale requests are aborted automatically.

idle

debounceSignal()

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'

debounceSignal() · Live

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.

raw (instant) (empty)
debounced (empty)
Event timeline

optimistic() · Pending Local Intent

Queue optimistic updates immediately, then commit or roll back when the request settles.

serverLikes() 0
optimisticLikes() 0
pendingCount() 0