SolidJS Cheat Sheet

Quick reference for SolidJS — signals, effects, stores, control flow, context, and component patterns. Build fast reactive UIs with fine-grained reactivity.

Getting Started Signals (Reactive State) Effects & Memos Control Flow Components Stores (Deep Reactivity) Context & Props SolidStart (Meta-Framework)

Getting Started

npx degit solidjs/templates/ts my-app Create TypeScript project
npx degit solidjs/templates/js my-app Create JavaScript project
npm create solid@latest Create with SolidStart (meta-framework)
npm run dev Start dev server (Vite)
npm run build Build for production
import { render } from "solid-js/web" Import render function
render(() => , document.getElementById("root")!) Mount app to DOM

Signals (Reactive State)

const [count, setCount] = createSignal(0) Create a signal (getter + setter)
count() Read signal value (call as function!)
setCount(5) Set signal to value
setCount(prev => prev + 1) Update based on previous value
const doubled = () => count() * 2 Derived value (just a function)
const [user, setUser] = createSignal({ name: "Alice" }) Signal with object
setUser({ ...user(), name: "Bob" }) Update object signal (replace)

Effects & Memos

createEffect(() => { console.log(count()) }) Run side effect when dependencies change
createEffect(on(count, (v) => { ... })) Explicit dependency tracking
createEffect(on(count, (v) => { ... }, { defer: true })) Skip initial run
const value = createMemo(() => expensiveCalc(count())) Cached derived value
onMount(() => { ... }) Run once after component mounts
onCleanup(() => { ... }) Cleanup on component unmount
const [data] = createResource(fetchUser) Async data fetching
const [data] = createResource(userId, fetchUser) Resource with source signal

Control Flow Components

}> Conditional rendering
{(item, i) =>
  • {item}
  • }
    List rendering (keyed by reference)
    {(item, i) =>
  • {item()}
  • }
    List rendering (keyed by index)
    ... Switch/match rendering
    Dynamic component selection
    Render outside component tree

    {err.message}

    }>...
    Error boundary
    }>{data()} Suspense for async resources

    Stores (Deep Reactivity)

    const [store, setStore] = createStore({ todos: [], filter: "all" }) Create store (deep reactive)
    store.todos[0].text Read nested store property
    setStore("filter", "active") Set top-level property
    setStore("todos", todo => [...todo, newTodo]) Update array in store
    setStore("todos", 0, "completed", true) Update nested property by path
    setStore("todos", t => t.id === id, "completed", c => !c) Update by predicate
    const [state, setState] = createStore({}, { name: "debug" }) Named store (DevTools)
    import { produce } from "solid-js/store" Immer-like mutations
    setStore(produce(s => { s.todos.push(newTodo) })) Mutate store with produce

    Context & Props

    const ThemeCtx = createContext("light") Create context with default
    ... Provide context value
    const theme = useContext(ThemeCtx) Consume context
    const [local, others] = splitProps(props, ["class", "children"]) Split props (avoid destructuring!)
    const merged = mergeProps({ size: "md" }, props) Merge props with defaults
    props.children Access children (do NOT destructure props)
    Polymorphic component pattern

    SolidStart (Meta-Framework)

    src/routes/index.tsx → / (file-based routing)
    src/routes/blog/[slug].tsx → /blog/:slug (dynamic route)
    export default function Page() { ... } Page component
    "use server" Mark function as server-only
    const data = createAsync(() => getUser()) Server function + async data
    const submit = useAction(createTodo) Use server action for mutations
    About Client-side navigation link
    export const route = { preload: () => getUser() } Preload data for route

    Try It Live

    Test these patterns with our free JSON Formatter. No signup needed.

    Open JSON Formatter →
    Step-by-Step Guide

    How to Build a CSS Grid Layout

    Read Guide →

    More Cheat Sheets