v0.20.230 - 20.4 / 7.7

Reactivity

Reactive primitives are introduced as needed through a clean and abstracted API. It currently leverages a customized version of the SolidJS Core, refactored to classes.

# Reactive Functions

nameargumentsreturnsdescription
signal(initialValue?, { equals?: false | (a, b) => boolean })[read, write, update] & { read, write, update }creates a signal. The return value doubles as a tuple ([read, write, update]) and an object ({ read, write, update }), so destructure whichever form you prefer. read() returns the current value; write(next) assigns a new value and returns true when it changed. update(fn) calls fn(prev) without tracking and writes the returned value — prefer it over write whenever the new value depends on the old, so you don't re-read the signal (and don't track the read). Pass equals: false to notify on every write (even when the value is the same), or a custom comparator.
memofnsignalread-only signal that will update when the return value of the function changes, memos are lazy
derived(...fn)signallazy, writable version of memo that unwraps and tracks functions and promises recursively. The function won't run unless the result is read; writing to the returned signal overrides the computed value.
externalSignal(initialValue, options?)signalsignal tailored for arrays of objects with an id key. Writing patches by id, preserving references for items that are unchanged. Useful for syncing server data without introducing a store.
root(dispose => ...)return value of fncreates a new top-level tracking scope. The callback receives a dispose function that tears down everything created inside. Reactive work that outlives a component (long-lived subscriptions, imperative rendering) belongs in a root.
effectfnvoidruns fn once immediately, then again whenever any signal it reads changes. Effects are scheduled — they may run later in the microtask queue; use syncEffect if you need synchronous execution.
on(depend, fn)voideffect with explicit dependencies. Only depend is tracked; fn runs untracked each time depend changes. Handy when the handler reads other signals you don't want as dependencies.
syncEffectfnvoidlike effect, but runs synchronously whenever a dependency changes instead of being queued for the next scheduler tick. Use when you need the side effect to land before the current call returns.
asyncEffect(previous: Promise<any> | undefined) => anyvoideffect for async work, serialised by default. On each run the callback receives the promise from the previous run (or undefined on the first run); await it to ensure the previous async run finishes before starting new work.
listener()current listener | undefinedreturns the currently-running reactive listener (the tracking scope an inner computation is inside), or undefined if there is none. Useful for introspection.
untrackfnreturn value of fnruns fn without establishing reactive dependencies on anything it reads
batchfnreturn value of fngroups writes so dependents re-run once at the end of fn instead of after each individual write.
action(...cbs)functionbuilds an action handler. Returns a function that, when called, runs cbs[0] with the received args and chains the remaining callbacks as continuations, unwrapping any returned functions or promises recursively. Cancels automatically if the owner is disposed — handy for async event handlers.
catchError(fn, onError)return value of fn | undefinedruns fn inside an error boundary. If it throws (synchronously or via a reactive dependency), onError(err) is called and the error does not bubble. Returns the value of fn, or undefined if it threw.
cleanupfnfnregisters fn to run when the current reactive scope is disposed. Returns the same function so you can keep a reference. Callbacks run in reverse-registration order (LIFO).
owned(fn, onCancel?)functioncaptures the current owner and returns a function bound to it. Calling that function re-runs fn under the captured owner, as long as the owner hasn't been disposed. If the owner is disposed before the function is called, onCancel runs instead. Useful for scheduling work (timers, promises, events) that must not outlive the component that scheduled it.
withValue(value, fn)voidresolves value and calls fn(resolved). Functions are unwrapped inside an effect (so fn re-runs on change); promises and arrays of functions/promises are resolved recursively. Plain values call fn immediately.
isResolved(...deriveds)booleantrue once every passed derived has resolved at least once. Useful with Suspense to know when async-driven derived values are ready.
map(iterable, callback, noSort?, fallback?, reactiveIndex?)rendered outputreactive equivalent of array.map. Tracks an iterable (array, set, map, signal returning one) and only re-runs callback for added/removed/changed entries — existing rows keep their state. Powers the <For/> component.