@zuzjs/store
v0.1.8
Published
ZuzJS State Manager
Readme
@zuzjs/store
High-performance global state manager for React.
Install
npm install @zuzjs/storeor
pnpm add @zuzjs/storeQuick Start
import createStore, { useStore } from "@zuzjs/store";
const { Provider } = createStore("app", {
count: 0,
loading: false,
token: null,
});
function Counter() {
const { count, dispatch } = useStore<{ count: number }>("app", s => ({ count: s.count }));
return (
<button onClick={() => dispatch({ count: count + 1 })}>
{count}
</button>
);
}
export default function App() {
return (
<Provider>
<Counter />
</Provider>
);
}API
createStore(key, initialState, mode?)
Creates (or returns) a store and its Provider.
const { Provider } = createStore("user", {
uid: null,
name: null,
email: null,
loading: true,
});You can pass scheduler mode directly at creation time:
const { Provider } = createStore(
"app",
{ count: 0, loading: false },
"microtask",
);Available modes:
"microtask"(default)"raf""sync"
useStore(key, selector?, equalityFn?)
key: store key created withcreateStoreselector: optional selector for slice subscriptionsequalityFn: optional comparison function for selector output
const state = useStore("app");
const tokenState = useStore("app", s => ({ token: s.token }));
const profile = useStore("user", s => s.profile, (a, b) => a?.id === b?.id);dispatch(payload) returns Promise<void>
Dispatch is async and awaitable.
const { dispatch } = useStore("app");
await dispatch({ loading: true });
dispatch({ token: "abc" }).then(() => {
// runs after the queued flush that included this dispatch
});Performance Features
1) Burst Coalescing (built-in)
Synchronous burst updates are merged into a single flush per store key.
const { dispatch } = useStore("app");
dispatch({ a: 1 });
dispatch({ b: 2 });
dispatch({ c: 3 });
// internally coalesced before notify2) batch(callback)
Group updates and notify once at batch end.
import { batch } from "@zuzjs/store";
batch(() => {
dispatch({ loading: true });
dispatch({ token: "new-token" });
dispatch({ loading: false });
});3) setStoreScheduleMode(key, mode)
Control flush timing strategy per store:
"microtask"(default): fastest general-purpose queueing"raf": align updates with animation frame"sync": flush immediately
import { setStoreScheduleMode } from "@zuzjs/store";
setStoreScheduleMode("app", "microtask");
setStoreScheduleMode("feed", "raf");
setStoreScheduleMode("critical", "sync");Compatibility Notes
Existing syntax remains valid:
useStore("app");
useStore("app", selector);
dispatch({ x: 1 });
createStore("app", { x: 1 });New capabilities are additive:
useStore("app", selector, equalityFn);
await dispatch({ x: 1 });
createStore("app", { x: 1 }, "raf");Recommended Patterns
- Use selectors to minimize renders in large trees.
- Use
equalityFnfor derived objects that would otherwise be recreated. - Keep payloads shallow and targeted for better merge/bailout behavior.
- Use
rafmode for UI animation-heavy streams. - Use
batchfor chained updates that should notify once.
Full Example
import createStore, { batch, setStoreScheduleMode, useStore } from "@zuzjs/store";
const { Provider } = createStore("app", { count: 0, loading: false }, "microtask");
setStoreScheduleMode("app", "microtask");
function Controls() {
const { count, dispatch } = useStore<{ count: number }>("app", s => ({ count: s.count }));
const burst = async () => {
batch(() => {
dispatch({ loading: true });
dispatch({ count: count + 1 });
dispatch({ count: count + 2 });
dispatch({ loading: false });
});
await dispatch({ count: count + 3 });
};
return <button onClick={burst}>Count: {count}</button>;
}
export default function App() {
return (
<Provider>
<Controls />
</Provider>
);
}