SolidJS is a declarative JavaScript framework for building user interfaces through fine-grained reactivity—a system where signals directly drive DOM updates without a virtual DOM. Unlike React, Solid components run once as setup functions, establishing reactive connections that persist; signals, effects, and memos form a reactive graph where changes automatically flow to dependent nodes. Understanding that components don't re-run but reactive primitives do is fundamental: the JSX returned creates real DOM nodes with subscriptions that update surgically when dependencies change, delivering near-constant performance regardless of application size or complexity.
What This Cheat Sheet Covers
This topic spans 17 focused tables and 95 indexed concepts, 79 flashcards. Below is a complete table-by-table outline of this topic, spanning foundational concepts through advanced details.
A jump-to index of every table row in this cheat sheet.
An interactive map of every table and concept in this topic.
Table 1: Core Reactive Primitives
Signals, effects, and memos form the foundation of SolidJS reactivity. Each primitive tracks dependencies automatically—signals hold state, memos cache derived values, and effects run side effects when dependencies update.
| Primitive | Example | Description | |
|---|---|---|---|
const [count, setCount] = createSignal(0);setCount(count() + 1); | • Creates a reactive getter-setter pair for state management • calling the getter inside a tracking scope (JSX, effect, memo) registers a dependency | ||
createEffect(() => { console.log(count());}); | • Runs a side effect whenever tracked signals change • auto-subscribes to signals read inside the function • ideal for DOM manipulation or external integrations | ||
const doubled = createMemo(() => count() * 2); | • Creates a cached derived value that recomputes only when dependencies change • prevents redundant calculations by tracking upstream signals | ||
const dispose = createRoot((dispose) => { const [s, setS] = createSignal(0); return dispose;}); | • Establishes a top-level reactive scope outside components • owns all nested computations and cleanup • disposing the root cleans up all children | ||
const val = untrack(() => count()); | • Reads signals without tracking dependencies • useful when you need a signal's value inside an effect but don't want to re-run when it changes | ||
batch(() => { setA(1); setB(2);}); | • Groups multiple signal updates to trigger dependent effects once • prevents intermediate re-runs • automatically applied within event handlers | ||
createEffect(on(count, (v) => console.log(v))); | • Creates an effect with explicit dependencies • separates the dependency list from the callback • useful for precise control over when effects run |