
Research
TeamPCP Compromises Telnyx Python SDK to Deliver Credential-Stealing Malware
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.
@solidjs/signals
Advanced tools
The reactive core that powers SolidJS 2.0. This is a standalone signals library designed for rendering — it 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
isPending(data); // true while loading
latest(data); // last resolved value
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 async accessor is loading |
latest(accessor) | Get the last resolved value of an async accessor |
refresh(accessor) | Re-trigger an async computation |
isRefreshing(accessor) | Check if an async accessor is refreshing |
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 |
pnpm install
pnpm build # Rollup build (dev/prod/node outputs)
pnpm test # Run tests
pnpm test:watch # Watch mode
pnpm test:gc # Tests with GC exposed
pnpm bench # Benchmarks
pnpm format # Prettier + import sorting
MIT
FAQs
SolidJS' standalone reactivity implementation
The npm package @solidjs/signals receives a total of 1,112 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.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.

Security News
/Research
Widespread GitHub phishing campaign uses fake Visual Studio Code security alerts in Discussions to trick developers into visiting malicious website.