
Security News
/Research
Fake Corepack Site Distributes Infostealer and Proxyware to Developers
A fake corepack.org site is impersonating the Node.js tool and delivers an infostealer and proxyware to developers who download it.
@solidjs/signals
Advanced tools
Solid's reactive primitives: signals, memos, effects, stores, and async-aware computations.
The reactive core that powers SolidJS 2.0. It is developed in the Solid monorepo and includes first-class support for async, transitions, optimistic updates, and deeply reactive stores that go beyond what general-purpose signals libraries offer.
Status: Beta — this package is the reactive foundation of SolidJS 2.0 Beta. The API is stabilizing but may still have breaking changes before a final release.
npm install @solidjs/signals
# or
pnpm add @solidjs/signals
@solidjs/signals is a push-pull hybrid reactive system. Signals hold values, computeds derive from them, and effects run side effects — all connected through an automatic dependency graph. Updates are batched and flushed asynchronously via microtask, giving you consistent state without glitches.
import { createEffect, createMemo, createRoot, createSignal, flush } from "@solidjs/signals";
createRoot(() => {
const [count, setCount] = createSignal(0);
const doubled = createMemo(() => count() * 2);
createEffect(
() => doubled(),
value => {
console.log("Doubled:", value);
}
);
setCount(5);
flush(); // "Doubled: 10"
});
Signal writes are batched — reads after a write won't reflect the new value until flush() runs. This prevents glitches and unnecessary recomputation.
const [a, setA] = createSignal(1);
const [b, setB] = createSignal(2);
setA(10);
setB(20);
// Neither has updated yet — both writes are batched
flush(); // Now both update and downstream effects run once
const [value, setValue] = createSignal(initialValue, options?);
Reactive state with a getter/setter pair. Supports custom equality via options.equals.
const derived = createMemo(() => expensive(signal()));
Read-only derived values that cache their result and only recompute when dependencies change. Supports async compute functions — return a Promise or AsyncIterable and downstream consumers will wait automatically.
// Two-phase: compute tracks dependencies, effect runs side effects
createEffect(
() => count(),
value => {
console.log(value);
}
);
// Render-phase effect (runs before user effects)
createRenderEffect(
() => count(),
value => {
updateDOM(value);
}
);
Effects split tracking from execution. createEffect and createRenderEffect take a compute function (for tracking) and an effect function (for side effects).
Pass a function to createSignal to get a writable derived value — a memo you can also set:
const [value, setValue] = createSignal(prev => transform(source(), prev), initialValue);
Computeds can return promises or async iterables. The reactive graph handles this automatically — previous values are held in place until the async work resolves, so downstream consumers never see an inconsistent state.
const data = createMemo(async () => {
const response = await fetch(`/api/items?q=${query()}`);
return response.json();
});
// Check async state for this read
isPending(data); // true while an unrevealed value change is in flight for this read
latest(data); // last resolved value; follows the not-ready path if no value has resolved yet
Use action() to coordinate async workflows with the reactive graph:
const save = action(function* (item) {
yield fetch("/api/save", { method: "POST", body: JSON.stringify(item) });
});
Optimistic signals show an immediate value while async work is pending, then automatically revert when it settles:
const [optimisticCount, setOptimisticCount] = createOptimistic(0);
// Immediate UI update — reverts when the async work resolves
setOptimisticCount(count + 1);
Also available for stores via createOptimisticStore().
Proxy-based deeply reactive objects with per-property tracking:
import { createStore, reconcile } from "@solidjs/signals";
const [store, setStore] = createStore({ todos: [], filter: "all" });
// Setter takes a mutating callback — mutations are intercepted by the proxy
setStore(s => {
s.filter = "active";
});
setStore(s => {
s.todos.push({ text: "New", done: false });
});
setStore(s => {
s.todos[0].done = true;
});
// Reconcile from server data
setStore(s => {
reconcile(serverTodos, "id")(s.todos);
});
Derived stores that transform data reactively:
import { createProjection } from "@solidjs/signals";
const filtered = createProjection(
draft => {
draft.items = store.todos.filter(t => !t.done);
},
{ items: [] }
);
Intercept async loading and error states in the reactive graph:
import { createErrorBoundary, createLoadingBoundary } from "@solidjs/signals";
createErrorBoundary(
() => riskyComputation(),
(error, reset) => handleError(error())
);
createLoadingBoundary(
() => asyncContent(),
() => showFallback()
);
All reactive nodes exist within an owner tree that handles disposal and context propagation:
import { createContext, createRoot, getContext, onCleanup, setContext } from "@solidjs/signals";
const ThemeContext = createContext("light");
createRoot(dispose => {
setContext(ThemeContext, "dark");
createEffect(
() => getContext(ThemeContext),
theme => {
console.log("Theme:", theme);
}
);
onCleanup(() => console.log("Disposed"));
// Call dispose() to tear down the tree
});
| Function | Description |
|---|---|
flush() | Process all pending updates |
untrack(fn) | Run fn without tracking dependencies |
isPending(accessor) | Check if an unrevealed value change is in flight for a read |
latest(accessor) | Get the last resolved value, or follow not-ready if none exists |
refresh(accessor) | Re-trigger an async computation (a quiet re-ask — not pending) |
affects(target, key?) | Declare that in-flight work will change the targeted data (reads pending until settle) |
resolve(fn) | Returns a promise that resolves when a reactive expression settles |
mapArray(list, mapFn) | Reactive array mapping with keyed reconciliation |
repeat(count, mapFn) | Reactive repeat based on a reactive count |
onSettled(fn) | Run a callback after the current flush cycle completes |
snapshot(store) | Returns a non-reactive copy of a store, preserving unmodified references |
reconcile(value, key) | Returns a diffing function for updating stores from new data |
merge(...sources) | Reactively merges multiple objects/stores, last source wins |
omit(props, ...keys) | Creates a reactive view of an object with specified keys removed |
deep(store) | Tracks all nested changes on a store |
storePath(...path) | Path-based setter for stores as an alternative to mutating callbacks |
From the monorepo root:
pnpm install
pnpm --filter @solidjs/signals build
pnpm --filter @solidjs/signals test
pnpm --filter @solidjs/signals test:watch
pnpm --filter @solidjs/signals test:gc
pnpm --filter @solidjs/signals bench
MIT
FAQs
SolidJS' standalone reactivity implementation
The npm package @solidjs/signals receives a total of 8,005 weekly downloads. As such, @solidjs/signals popularity was classified as popular.
We found that @solidjs/signals demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
/Research
A fake corepack.org site is impersonating the Node.js tool and delivers an infostealer and proxyware to developers who download it.

Research
/Security News
A large-scale campaign abused GitHub Actions in compromised repositories to exploit CVE-2026-41940 in cPanel and WHM and steal server credentials.

Security News
Five frontier LLMs generated the same nonexistent package names, leaving 53 available for potential slopsquatting across PyPI and npm.