Covers separating stores by domain (auth, cart, ui, theme) rather than one giant store, SOLID file organization (store.ts, store.interface.ts, use-store.ts), and forbidden patterns (persisting auth tokens, v4 syntax, skipping useShallow). This is the plain-React variant of Zustand (no App Router request-isolation concerns) — for Next.js App Router see nextjs-zustand, and for server state use TanStack Query instead of this skill.
Zustand for React
Minimal, scalable state management with React 18+ useSyncExternalStore.
Agent Workflow (MANDATORY)
Before ANY implementation, spawn 3 agents in parallel, one Agent call each with a name:
- fuse-ai-pilot:explore-codebase - Analyze existing stores and state patterns
- fuse-ai-pilot:research-expert - Verify latest Zustand v5 docs via Context7/Exa
- mcp__context7__query-docs - Check middleware and TypeScript patterns
After implementation, run fuse-ai-pilot:sniper for validation.
Overview
When to Use
- Managing global state in React applications
- Need state shared across components
- Persisting state to localStorage/sessionStorage
- Building UI state (modals, sidebars, theme, cart)
- Replacing React Context for complex state
Why Zustand v5
| Feature |
Benefit |
| Minimal API |
Simple create() function, no boilerplate |
| React 18 native |
useSyncExternalStore, no shims needed |
| TypeScript first |
Full inference with currying pattern |
| Middleware stack |
devtools, persist, immer composable |
| Bundle size |
~2KB gzipped, smallest state library |
| No providers |
Direct store access, no Context wrapper |
Critical Rules
- useShallow for arrays/objects - Prevent unnecessary re-renders
- Currying syntax v5 -
create<State>()((set) => ({...}))
- SOLID paths - Stores in
modules/[feature]/src/stores/
- Separate stores - One store per domain (auth, cart, ui, theme)
- Server state elsewhere - Use TanStack Query for server state
SOLID Architecture
Module Structure
Stores organized by feature module:
modules/cores/stores/ - Shared stores (theme, ui)
modules/auth/src/stores/ - Auth state
modules/cart/src/stores/ - Cart state
modules/[feature]/src/interfaces/ - Store types
File Organization
| File |
Purpose |
Max Lines |
store.ts |
Store creation with create() |
50 |
store.interface.ts |
TypeScript interfaces |
30 |
use-store.ts |
Custom hook with selector |
20 |
Key Concepts
Store Creation (v5 Syntax)
Double parentheses required for TypeScript inference. Currying pattern ensures full type safety.
Middleware Composition
Stack middlewares: devtools -> persist -> immer. Order matters for TypeScript types.
Selector Pattern
Always use useStore((s) => s.field) for performance. Use useShallow for array/object selectors.
Reference Guide
| Need |
Reference |
| Initial setup |
installation.md |
| Store patterns |
store-patterns.md |
| Middleware |
middleware.md |
| TypeScript |
typescript.md |
| Slices pattern |
slices.md |
| Auto selectors |
auto-selectors.md |
| Reset state |
reset-state.md |
| Subscribe API |
subscribe-api.md |
| Testing |
testing.md |
| Migration v4→v5 |
migration-v5.md |
Best Practices
- Selector pattern - Always use
useStore((s) => s.field) for performance
- useShallow - Wrap array/object selectors to prevent re-renders
- Separate stores - One store per domain (auth, cart, ui, theme)
- Server data elsewhere - Use TanStack Query for server state
- DevTools in dev only - Wrap devtools in process.env check
- Partialize persist - Only persist necessary fields, never tokens
Forbidden Patterns
| Pattern |
Reason |
Alternative |
| Persisting auth tokens |
Security vulnerability |
httpOnly cookies |
| Without useShallow on objects |
Excessive re-renders |
useShallow(selector) |
| v4 syntax |
TypeScript inference broken |
v5 currying create<T>()() |
| Giant monolithic store |
Hard to maintain |
Slices or separate stores |
1---2name: react-state3description: Zustand v5 state management for React. Use when implementing global state, stores, persist, or client-side state.4---56<objective>7Implements Zustand v5 global state management for React applications: the v5 currying syntax (`create<State>()((set) => ({...}))`), the selector pattern (`useStore((s) => s.field)`), `useShallow` for array/object selectors to prevent unnecessary re-renders, and middleware composition (devtools → persist → immer, order-sensitive for TypeScript).89Covers separating stores by domain (auth, cart, ui, theme) rather than one giant store, SOLID file organization (`store.ts`, `store.interface.ts`, `use-store.ts`), and forbidden patterns (persisting auth tokens, v4 syntax, skipping `useShallow`). This is the plain-React variant of Zustand (no App Router request-isolation concerns) — for Next.js App Router see nextjs-zustand, and for server state use TanStack Query instead of this skill.10</objective>1112# Zustand for React1314Minimal, scalable state management with React 18+ useSyncExternalStore.1516## Agent Workflow (MANDATORY)1718Before ANY implementation, spawn 3 agents in parallel, one `Agent` call each with a `name`:19201. **fuse-ai-pilot:explore-codebase** - Analyze existing stores and state patterns212. **fuse-ai-pilot:research-expert** - Verify latest Zustand v5 docs via Context7/Exa223. **mcp__context7__query-docs** - Check middleware and TypeScript patterns2324After implementation, run **fuse-ai-pilot:sniper** for validation.2526---2728## Overview2930### When to Use3132- Managing global state in React applications33- Need state shared across components34- Persisting state to localStorage/sessionStorage35- Building UI state (modals, sidebars, theme, cart)36- Replacing React Context for complex state3738### Why Zustand v53940| Feature | Benefit |41|---------|---------|42| Minimal API | Simple create() function, no boilerplate |43| React 18 native | useSyncExternalStore, no shims needed |44| TypeScript first | Full inference with currying pattern |45| Middleware stack | devtools, persist, immer composable |46| Bundle size | ~2KB gzipped, smallest state library |47| No providers | Direct store access, no Context wrapper |4849---5051## Critical Rules52531. **useShallow for arrays/objects** - Prevent unnecessary re-renders542. **Currying syntax v5** - `create<State>()((set) => ({...}))`553. **SOLID paths** - Stores in `modules/[feature]/src/stores/`564. **Separate stores** - One store per domain (auth, cart, ui, theme)575. **Server state elsewhere** - Use TanStack Query for server state5859---6061## SOLID Architecture6263### Module Structure6465Stores organized by feature module:6667- `modules/cores/stores/` - Shared stores (theme, ui)68- `modules/auth/src/stores/` - Auth state69- `modules/cart/src/stores/` - Cart state70- `modules/[feature]/src/interfaces/` - Store types7172### File Organization7374| File | Purpose | Max Lines |75|------|---------|-----------|76| `store.ts` | Store creation with create() | 50 |77| `store.interface.ts` | TypeScript interfaces | 30 |78| `use-store.ts` | Custom hook with selector | 20 |7980---8182## Key Concepts8384### Store Creation (v5 Syntax)8586Double parentheses required for TypeScript inference. Currying pattern ensures full type safety.8788### Middleware Composition8990Stack middlewares: devtools -> persist -> immer. Order matters for TypeScript types.9192### Selector Pattern9394Always use `useStore((s) => s.field)` for performance. Use `useShallow` for array/object selectors.9596---9798## Reference Guide99100| Need | Reference |101|------|-----------|102| Initial setup | [installation.md](references/installation.md) |103| Store patterns | [store-patterns.md](references/store-patterns.md) |104| Middleware | [middleware.md](references/middleware.md) |105| TypeScript | [typescript.md](references/typescript.md) |106| Slices pattern | [slices.md](references/slices.md) |107| Auto selectors | [auto-selectors.md](references/auto-selectors.md) |108| Reset state | [reset-state.md](references/reset-state.md) |109| Subscribe API | [subscribe-api.md](references/subscribe-api.md) |110| Testing | [testing.md](references/testing.md) |111| Migration v4→v5 | [migration-v5.md](references/migration-v5.md) |112113---114115## Best Practices1161171. **Selector pattern** - Always use `useStore((s) => s.field)` for performance1182. **useShallow** - Wrap array/object selectors to prevent re-renders1193. **Separate stores** - One store per domain (auth, cart, ui, theme)1204. **Server data elsewhere** - Use TanStack Query for server state1215. **DevTools in dev only** - Wrap devtools in process.env check1226. **Partialize persist** - Only persist necessary fields, never tokens123124---125126## Forbidden Patterns127128| Pattern | Reason | Alternative |129|---------|--------|-------------|130| Persisting auth tokens | Security vulnerability | httpOnly cookies |131| Without useShallow on objects | Excessive re-renders | `useShallow(selector)` |132| v4 syntax | TypeScript inference broken | v5 currying `create<T>()()` |133| Giant monolithic store | Hard to maintain | Slices or separate stores |