Solid quick start
@zhuangtai-js/solid fits Solid components or roots that need to read, write, and automatically bind Core subscriptions to cleanup.
Requirements and install
Section titled “Requirements and install”@zhuangtai-js/core^0.5.0- Solid >=1.5 <2
pnpm add @zhuangtai-js/core @zhuangtai-js/solid solid-jsMinimal counter
Section titled “Minimal counter”Keep the state model outside the component and call the adapter inside a Solid owner. The updater returns a new object and array instead of mutating the atom value:
import { atom, computed } from "@zhuangtai-js/core";
export type CounterState = { count: number; history: number[];};
export const counterAtom = atom<CounterState>({ count: 0, history: [] });export const doubleAtom = computed(() => counterAtom.get().count * 2);
export function incrementCounter(state: CounterState): CounterState { const count = state.count + 1; return { ...state, count, history: [...state.history, count] };}import { createAtomSignal, createAtomValue, createSetAtom } from "@zhuangtai-js/solid";import { counterAtom, doubleAtom, incrementCounter } from "../state/counter";
export function Counter() { const [counter, setCounter] = createAtomSignal(counterAtom); const double = createAtomValue(doubleAtom); const reset = createSetAtom(counterAtom);
return ( <section> <button type="button" onClick={() => setCounter(incrementCounter)}> {counter().count} × 2 = {double()} </button> <button type="button" onClick={() => reset({ count: 0, history: [] })}> reset ({counter().history.length}) </button> </section> );}Place the state module
Section titled “Place the state module”Put atom, computed, the type, and the updater in src/state/ or src/features/<feature>/state.ts; components should connect accessors only inside an owner. Client module-level atoms can be shared. SSR user or request state must be created independently for every request.
Choose read and write access
Section titled “Choose read and write access”- Read-write:
createAtomSignal(counterAtom)returns[Accessor<Value>, setter]. - Read-only:
createAtomValue(doubleAtom)returns anAccessor<Value>, read asdouble()in JSX. - Setter-only:
createSetAtom(counterAtom)returns a setter without reading or subscribing and can run outside an owner.
Client read APIs must run in a Solid component or createRoot owner; setter-only access does not require an owner.
Lifecycle and SSR boundary
Section titled “Lifecycle and SSR boundary”On the client, createAtomValue binds the Core watcher to the current owner and stops it with onCleanup; when you create a manual createRoot, keep and call its returned dispose. Core still owns immediate set, synchronous watch, Object.is equality, and immutable reference boundaries.
The standard server renderToString path uses isServer from solid-js/web to read one snapshot without checking for an owner or creating a Core subscription. SSR still needs independent atoms per request; do not share mutable server module-scope state.
Persistence
Section titled “Persistence”When state must survive a reload, see the Persist reference and compose @zhuangtai-js/persist in the state creator. Persistence controls belong to the state module; Solid components only choose accessor and setter APIs.
API reference
Section titled “API reference”createAtomValue: converts aReadableAtomto an accessor.createSetAtom: returns a setter that does not subscribe to the value.createAtomSignal: combines an accessor and setter.
See the Solid reference for complete owner, cleanup, SSR, and reference semantics.
Next steps
Section titled “Next steps”- Core Concepts: learn synchronous
get,set,watch, andcomputed. - Framework adapter chooser: compare owner and lifecycle boundaries.
- Persist reference: configure storage, hydration, and lifecycle controls.