About zustand
The zustand skill covers Zustand v5, a lightweight global state manager for React. It is for React developers and focuses on typed stores, selectors, composable middleware, and organizing larger stores with slices.
Key features
- 01Type-safe global state stores
- 02Atomic selectors to limit re-renders
- 03Persist and DevTools middleware
- 04Immer and selector subscription middleware
- 05Domain-based state slices
Use cases
- 01Sharing client state across components
- 02Persisting user preferences
- 03Structuring multi-domain application state
- 04Managing state outside React
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ oakoss/ agent-skills --skill zustandAfter installing, type/zustandin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
references/middleware.mdmigration.mdslices-pattern.mdssr-hydration.mdstore-patterns.mdtesting.mdDetails
From the project READMEZustand State Management
Overview
Zustand v5 is a lightweight global state manager for React built on useSyncExternalStore. Requires React 18+ (uses useSyncExternalStore internally). When using createWithEqualityFn, install use-sync-external-store as a peer dependency. It provides type-safe stores, atomic selectors for minimal re-renders, composable middleware (persist, devtools, immer, subscribeWithSelector), and a slices pattern for large applications. Use Zustand for client-only global state; use TanStack Query for server-fetched data.
When to use: Client-side global state, persistent user preferences, complex multi-domain stores, cross-component state sharing, vanilla (non-React) state management.
When NOT to use: Server state with caching needs (use TanStack Query), single-component state (use useState), simple prop drilling scenarios.
Quick Reference
| Pattern | API | Key Points |
|---|---|---|
| Basic store | create<T>()((set) => ({...})) | Double parentheses required for TS |
| Atomic selector | useStore(state => state.bears) | Only re-renders when selected value changes |
| Multiple values | useShallow(state => ({a, b})) | Import from zustand/react/shallow |
| Persist | persist(fn, { name }) | localStorage with SSR hydration handling |
| Devtools | devtools(fn, { name }) | Redux DevTools integration |
| SubscribeWithSelector | subscribeWithSelector(fn) | Subscribe to state slices outside React |
| Middleware order | devtools(persist(fn)) | Outer to inner wrapping |
| Slices pattern | StateCreator<Combined, [], [], Slice> | Split store by domain |
| SSR provider | createStore + React Context | Per-request stores prevent data leaks |
| Immer | immer(fn) | Safe nested state mutations |
| Vanilla store | createStore from zustand/vanilla | Use outside React |
| Reset store | set(store.getInitialState()) | Use getInitialState() for reliable reset |
| Derived values | useStore(s => s.items.length) | Compute in selector |
| Auto selectors | createSelectors(store) | Generate store.use.field() hooks automatically |
Common Mistakes
| Mistake | Correct Pattern |
|---|---|
Using create<T>(...) with single parentheses | Use create<T>()(...) double parentheses for correct TypeScript middleware inference |
Selecting full state object with useStore(state => state) | Use atomic selectors like state.bears or useShallow to avoid unnecessary re-renders |
Importing useShallow from zustand/shallow | Import from zustand/react/shallow; zustand/shallow exports the plain shallow function only |
| Creating new object references in selectors causing infinite loops | Use separate primitive selectors or wrap with useShallow from zustand/react/shallow |
| Using a global singleton store with SSR or Next.js | Use the StoreContext provider pattern with createStore to prevent data leaks between requests |
| Tracking initial state manually for reset | Use store.getInitialState() which Zustand provides automatically |
| Using Zustand for server-fetched data that needs caching and revalidation | Use TanStack Query for server state; reserve Zustand for client-only global state |
Delegation
- Store architecture and slices design: Use
Planagent to define domain boundaries, slice interfaces, and middleware composition order - Hydration and SSR debugging: Use
Taskagent to diagnose persist middleware issues, hydration mismatches, and Next.js provider setup - Migration from v4 to v5: Use
Exploreagent to find deprecated import paths, single-parentheses patterns, and legacy middleware usage - Testing strategy: Use
Taskagent to set up store mocks and test isolation patterns