Getting Started
Install @zap-studio/store and build your first store step by step.
Installation
npm install @zap-studio/storeyarn add @zap-studio/storepnpm add @zap-studio/storebun add @zap-studio/storedeno add jsr:@zap-studio/storeCreate a Store
createStore(initialState, actionsFactory?, options?) returns a store. initialState is the only required argument.
import { createStore } from "@zap-studio/store";
const counter = createStore({ count: 0 });
counter.getState(); // { count: 0 }
Add Actions
Pass a second argument: a function that receives set and get, and returns your actions. It runs once, at creation — actions are not rebuilt per render or per consumer.
const counter = createStore({ count: 0 }, (set, get) => ({
increment: () => set((s) => ({ count: s.count + 1 })),
reset: () => set(() => ({ count: 0 })),
}));
counter.get().increment();
counter.getState(); // { count: 1 }
set only takes an updater function — see set for why, and for the shallow-merge rule.
Read State
getState()returns state only.get()returns state and actions merged.
counter.getState(); // { count: 1 }
counter.get(); // { count: 1, increment: fn, reset: fn }
Subscribe to Changes
subscribe(listener) calls listener with the merged state (and actions) on every change, and returns a plain unsubscribe function:
const unsubscribe = counter.subscribe((state) => console.log(state.count));
counter.get().increment(); // logs 2
unsubscribe();
counter.get().increment(); // nothing logged
Derive a Value
derive(deps, fn) builds a cached value from one or more stores. It stays correct on its own — see derive for how the tracking works.
import { derive } from "@zap-studio/store";
const isEven = derive([counter], (s) => s.count % 2 === 0);
isEven.get(); // false
counter.get().increment();
isEven.get(); // true
Persist State
Pass { persist: { key, storage } } as the third argument to save and load state through localStorage-shaped storage:
const counter = createStore(
{ count: 0 },
(set) => ({ increment: () => set((s) => ({ count: s.count + 1 })) }),
{ persist: { key: "counter", storage: localStorage } },
);
See Persist for what gets saved and what does not.