Svelte quick start
@zhuangtai-js/svelte fits Svelte applications that want standard store syntax while preserving Core’s synchronous updates and reference semantics.
Requirements and install
Section titled “Requirements and install”@zhuangtai-js/core^0.5.0- Svelte >=4.2 <6
pnpm add @zhuangtai-js/core @zhuangtai-js/svelte svelteMinimal counter
Section titled “Minimal counter”Keep the state model in a plain TypeScript module; toWritable provides a read-write store and toReadable provides a read-only computed store. The update callback returns a new object and array:
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] };}<script lang="ts"> import { toReadable, toWritable } from "@zhuangtai-js/svelte"; import { counterAtom, doubleAtom, incrementCounter } from "../lib/counter";
const counter = toWritable(counterAtom); const double = toReadable(doubleAtom);
function reset() { counter.set({ count: 0, history: [] }); }</script>
<button type="button" on:click={() => counter.update(incrementCounter)}> {$counter.count} × 2 = {$double}</button><button type="button" on:click={reset}> reset ({$counter.history.length})</button>Place the state module
Section titled “Place the state module”Put atom, computed, the type, and the updater in src/lib/ or src/lib/<feature>/state.ts; components only convert them to stores. Module-level atoms suit browser-shared state. For SSR, create independent state for every request instead of sharing a mutable server module singleton.
Choose read and write access
Section titled “Choose read and write access”- Read-write:
toWritable(counterAtom)returns a standardWritablewith$counter,set, andupdate. - Read-only:
toReadable(doubleAtom)returns a standardReadablefor$doublein a template. - Setter-only: the Svelte adapter has no separate setter-only export; a command module can call
counterAtom.set(nextValue)directly without creating a store subscription.
When subscribing to toReadable or toWritable manually, keep and call the stopper returned by subscribe; Svelte automatically subscribes and cleans up $store usage in templates.
Lifecycle and SSR boundary
Section titled “Lifecycle and SSR boundary”The adapter implements the standard svelte/store protocol and adds no scheduling, batching, or browser API. Svelte owns subscription and cleanup for $store; manual subscribe calls must invoke their stopper at the lifecycle boundary. Core still decides when set takes effect, when watch runs, how Object.is equality works, and how immutable references are handled.
The SSR boundary comes from the underlying atoms and the application’s request lifecycle: create independent state and stores for every request, and never put user state in a mutable server module singleton. Keep the client initial value aligned with the server output during hydration.
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; Svelte components only consume the store.
API reference
Section titled “API reference”toReadable: converts aReadableAtomto a SvelteReadable.toWritable: converts a writableAtomto a SvelteWritablewithsetandupdate.
See the Svelte reference for complete store, subscription, and SSR semantics.
Next steps
Section titled “Next steps”- Core Concepts: learn the synchronous state primitives and immutable updates.
- Framework adapter chooser: compare native reactive APIs.
- Persist reference: configure storage, hydration, and lifecycle controls.