# SolidJS API Reference Complete reference for all SolidJS primitives, utilities, and component APIs. ## Basic Reactivity ### createSignal ```tsx import { createSignal } from "solid-js"; const [getter, setter] = createSignal(initialValue, options?); // Options interface SignalOptions { equals?: false | ((prev: T, next: T) => boolean); name?: string; internal?: boolean; } ``` **Examples:** ```tsx const [count, setCount] = createSignal(0); const [user, setUser] = createSignal(null); // Always update const [data, setData] = createSignal(obj, { equals: false }); // Custom equality const [items, setItems] = createSignal([], { equals: (a, b) => a.length === b.length }); // Setter forms setCount(5); // Direct value setCount(prev => prev + 1); // Functional update ``` ### createEffect ```tsx import { createEffect } from "solid-js"; createEffect(fn: (prev: T) => T, initialValue?: T, options?); // Options interface EffectOptions { name?: string; } ``` **Examples:** ```tsx // Basic createEffect(() => { console.log("Count:", count()); }); // With previous value createEffect((prev) => { console.log("Changed from", prev, "to", count()); return count(); }, count()); // With cleanup createEffect(() => { const handler = () => {}; window.addEventListener("resize", handler); onCleanup(() => window.removeEventListener("resize", handler)); }); ``` ### createMemo ```tsx import { createMemo } from "solid-js"; const getter = createMemo(fn: (prev: T) => T, initialValue?: T, options?); // Options interface MemoOptions { equals?: false | ((prev: T, next: T) => boolean); name?: string; } ``` **Examples:** ```tsx const doubled = createMemo(() => count() * 2); const filtered = createMemo(() => items().filter(i => i.active)); // Previous value const delta = createMemo((prev) => count() - prev, 0); ``` ### createResource ```tsx import { createResource } from "solid-js"; const [resource, { mutate, refetch }] = createResource( source?, // Optional reactive source fetcher, // (source, info) => Promise options? ); // Resource properties resource() // T | undefined resource.loading // boolean resource.error // any resource.state // "unresolved" | "pending" | "ready" | "refreshing" | "errored" resource.latest // T | undefined (last successful value) // Options interface ResourceOptions { initialValue?: T; name?: string; deferStream?: boolean; ssrLoadFrom?: "initial" | "server"; storage?: (init: T) => [Accessor, Setter]; onHydrated?: (key, info: { value: T }) => void; } ``` **Examples:** ```tsx // Without source const [users] = createResource(fetchUsers); // With source const [user] = createResource(userId, fetchUser); // With options const [data] = createResource(id, fetchData, { initialValue: [], deferStream: true }); // Actions mutate(newValue); // Update locally refetch(); // Re-fetch refetch(customInfo); // Pass to fetcher's info.refetching ``` ## Stores ### createStore ```tsx import { createStore } from "solid-js/store"; const [store, setStore] = createStore(initialValue); ``` **Update patterns:** ```tsx const [state, setState] = createStore({ user: { name: "John", age: 30 }, todos: [{ id: 1, text: "Learn Solid", done: false }] }); // Path syntax setState("user", "name", "Jane"); setState("user", "age", a => a + 1); setState("todos", 0, "done", true); // Array operations setState("todos", t => [...t, newTodo]); setState("todos", todos.length, newTodo); // Multiple paths setState("todos", { from: 0, to: 2 }, "done", true); setState("todos", [0, 2, 4], "done", true); setState("todos", i => i.done, "done", false); // Object merge (shallow) setState("user", { age: 31 }); // Keeps other properties ``` ### produce ```tsx import { produce } from "solid-js/store"; setState(produce(draft => { draft.user.age++; draft.todos.push({ id: 2, text: "New", done: false }); draft.todos[0].done = true; })); ``` ### reconcile ```tsx import { reconcile } from "solid-js/store"; // Replace with diff (minimal updates) setState("todos", reconcile(newTodosFromAPI)); // Options reconcile(data, { key: "id", merge: true }); ``` ### unwrap ```tsx import { unwrap } from "solid-js/store"; const raw = unwrap(store); // Non-reactive plain object ``` ### createMutable ```tsx import { createMutable } from "solid-js/store"; const state = createMutable({ count: 0, user: { name: "John" } }); // Direct mutation (like MobX) state.count++; state.user.name = "Jane"; ``` ### modifyMutable ```tsx import { modifyMutable, reconcile, produce } from "solid-js/store"; modifyMutable(state, reconcile(newData)); modifyMutable(state, produce(s => { s.count++ })); ``` ## Component APIs ### children ```tsx import { children } from "solid-js"; const resolved = children(() => props.children); // Access resolved(); // JSX.Element | JSX.Element[] resolved.toArray(); // Always array ``` ### createContext / useContext ```tsx import { createContext, useContext } from "solid-js"; const MyContext = createContext(defaultValue?); // Provider {children} // Consumer const value = useContext(MyContext); ``` ### createUniqueId ```tsx import { createUniqueId } from "solid-js"; const id = createUniqueId(); // "0", "1", etc. ``` ### lazy ```tsx import { lazy } from "solid-js"; const LazyComponent = lazy(() => import("./Component")); // Use with Suspense }> ``` ## Lifecycle ### onMount ```tsx import { onMount } from "solid-js"; onMount(() => { // Runs once after initial render console.log("Mounted"); }); ``` ### onCleanup ```tsx import { onCleanup } from "solid-js"; // In component onCleanup(() => { console.log("Cleaning up"); }); // In effect createEffect(() => { const sub = subscribe(); onCleanup(() => sub.unsubscribe()); }); ``` ## Reactive Utilities ### batch ```tsx import { batch } from "solid-js"; batch(() => { setA(1); setB(2); setC(3); // Effects run once after batch }); ``` ### untrack ```tsx import { untrack } from "solid-js"; createEffect(() => { console.log(a()); // Tracked console.log(untrack(() => b())); // Not tracked }); ``` ### on ```tsx import { on } from "solid-js"; // Explicit dependencies createEffect(on(count, (value, prev) => { console.log("Count changed:", prev, "->", value); })); // Multiple dependencies createEffect(on([a, b], ([a, b], [prevA, prevB]) => { console.log("Changed"); })); // Defer first run createEffect(on(count, (v) => console.log(v), { defer: true })); ``` ### mergeProps ```tsx import { mergeProps } from "solid-js"; const merged = mergeProps( { size: "medium", color: "blue" }, // Defaults props // Overrides ); ``` ### splitProps ```tsx import { splitProps } from "solid-js"; const [local, others] = splitProps(props, ["class", "onClick"]); // local.class, local.onClick // others contains everything else const [a, b, rest] = splitProps(props, ["foo"], ["bar"]); ``` ### createRoot ```tsx import { createRoot } from "solid-js"; const dispose = createRoot((dispose) => { const [count, setCount] = createSignal(0); // Use signals... return dispose; }); // Later dispose(); ``` ### getOwner / runWithOwner ```tsx import { getOwner, runWithOwner } from "solid-js"; const owner = getOwner(); // Later, in async code runWithOwner(owner, () => { createEffect(() => { // This effect has proper ownership }); }); ``` ### mapArray ```tsx import { mapArray } from "solid-js"; const mapped = mapArray( () => items(), (item, index) => ({ ...item, doubled: item.value * 2 }) ); ``` ### indexArray ```tsx import { indexArray } from "solid-js"; const mapped = indexArray( () => items(), (item, index) =>
{index}: {item().name}
); ``` ### observable ```tsx import { observable } from "solid-js"; const obs = observable(signal); obs.subscribe((value) => console.log(value)); ``` ### from ```tsx import { from } from "solid-js"; // Convert observable/subscribable to signal const signal = from(rxObservable); const signal = from((set) => { const unsub = subscribe(set); return unsub; }); ``` ### catchError ```tsx import { catchError } from "solid-js"; catchError( () => riskyOperation(), (err) => console.error("Error:", err) ); ``` ## Secondary Primitives ### createComputed ```tsx import { createComputed } from "solid-js"; // Like createEffect but runs during render phase createComputed(() => { setDerived(source() * 2); }); ``` ### createRenderEffect ```tsx import { createRenderEffect } from "solid-js"; // Runs before paint (for DOM measurements) createRenderEffect(() => { const height = element.offsetHeight; }); ``` ### createDeferred ```tsx import { createDeferred } from "solid-js"; // Returns value after idle time const deferred = createDeferred(() => expensiveComputation(), { timeoutMs: 1000 }); ``` ### createReaction ```tsx import { createReaction } from "solid-js"; const track = createReaction(() => { console.log("Something changed"); }); track(() => count()); // Start tracking ``` ### createSelector ```tsx import { createSelector } from "solid-js"; const isSelected = createSelector(selectedId); {(item) => (
{item.name}
)}
``` ## Components ### Show ```tsx }> // With callback (narrowed type) {(user) =>
{user().name}
}
``` ### For ```tsx }> {(item, index) =>
{index()}: {item.name}
}
``` ### Index ```tsx }> {(item, index) => } ``` ### Switch / Match ```tsx }> ``` ### Dynamic ```tsx import { Dynamic } from "solid-js/web"; Content ``` ### Portal ```tsx import { Portal } from "solid-js/web"; ``` ### ErrorBoundary ```tsx (

Error: {err.message}

)}>
``` ### Suspense ```tsx }> ``` ### SuspenseList ```tsx }> }> }> ``` ## Rendering ### render ```tsx import { render } from "solid-js/web"; const dispose = render(() => , document.getElementById("root")!); // Cleanup dispose(); ``` ### hydrate ```tsx import { hydrate } from "solid-js/web"; hydrate(() => , document.getElementById("root")!); ``` ### renderToString ```tsx import { renderToString } from "solid-js/web"; const html = renderToString(() => ); ``` ### renderToStringAsync ```tsx import { renderToStringAsync } from "solid-js/web"; const html = await renderToStringAsync(() => ); ``` ### renderToStream ```tsx import { renderToStream } from "solid-js/web"; const stream = renderToStream(() => ); stream.pipe(res); ``` ### isServer ```tsx import { isServer } from "solid-js/web"; if (isServer) { // Server-only code } ``` ## JSX Attributes ### ref ```tsx let el: HTMLDivElement;
console.log(e)} /> ``` ### classList ```tsx
``` ### style ```tsx
``` ### on:event (native) ```tsx
``` ### use:directive ```tsx function clickOutside(el: HTMLElement, accessor: () => () => void) { const handler = (e: MouseEvent) => { if (!el.contains(e.target as Node)) accessor()(); }; document.addEventListener("click", handler); onCleanup(() => document.removeEventListener("click", handler)); }
setOpen(false)} /> ``` ### prop:property ```tsx // Set as property, not attribute ``` ### attr:attribute ```tsx
// Force attribute ``` ### bool:attribute ```tsx ``` ### @once ```tsx
// Never updates ``` ## Types ```tsx import type { Component, ParentComponent, FlowComponent, VoidComponent, JSX, Accessor, Setter, Signal, Resource, Owner } from "solid-js"; // Component types const MyComponent: Component = (props) =>
; const Parent: ParentComponent = (props) =>
{props.children}
; const Flow: FlowComponent = (props) => props.children(item); const Void: VoidComponent = (props) => ; // Event types type Handler = JSX.EventHandler; type ChangeHandler = JSX.ChangeEventHandler; ```