Nextjs zustand
Skill fusengine/agents/plugins/nextjs-expert/skills/nextjs-zustand
Use when implementing global state, stores, persist, or hydration in Next.js 16 App Router Client Components with Zustand v5.From its SKILL.md
npx -y skills add fusengine/agents --skill nextjs-zustandAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 22 stars22 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
6.0 KB, ~1.3k tokens by cl100k_base, as published. Nobody here has run it
Covers skipHydration with the persist middleware plus manual rehydration in useEffect to avoid SSR mismatches, useShallow for array/object selectors, and SOLID file organization (store.ts, store-provider.tsx, use-store.ts). States explicitly that Zustand is Client-Components-only — never used in Server Components (fetch data directly there instead) and never used to persist auth tokens (use httpOnly cookies). Does not cover server state caching (see nextjs-tanstack-query for that).
</objective>
Zustand for Next.js 16
Minimal, scalable state management with React 18+ useSyncExternalStore.
Agent Workflow (MANDATORY)
Before ANY implementation, use TeamCreate to spawn 3 agents:
- 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 client-side state in Next.js App Router applications
- Need global state across Client Components only
- 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
- Client Components ONLY - Never use Zustand in Server Components
- Context pattern for App Router - Avoid global stores (request isolation)
- useShallow for arrays/objects - Prevent unnecessary re-renders
- skipHydration with persist - Required for SSR compatibility
- Currying syntax v5 -
create<State>()((set) => ({...})) - SOLID paths - Stores in
modules/[feature]/src/stores/
SOLID Architecture
Module Structure
Stores organized by feature module:
modules/cores/stores/- Shared stores (theme, ui)modules/auth/src/stores/- Auth statemodules/cart/src/stores/- Cart statemodules/[feature]/src/interfaces/- Store types
File Organization
| File | Purpose | Max Lines |
|---|---|---|
store.ts | Store creation with create() | 50 |
store.interface.ts | TypeScript interfaces | 30 |
store-provider.tsx | Context provider (App Router) | 40 |
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.
Context-Based Stores
For Next.js App Router, wrap stores in Context to prevent request-sharing. Use createStore from zustand/vanilla with useRef for initialization.
Middleware Composition
Stack middlewares: devtools → persist → immer. Order matters for TypeScript types.
Hydration Handling
Use skipHydration: true with persist middleware. Manually rehydrate in useEffect to avoid SSR mismatches.
Reference Guide
| Need | Reference |
|---|---|
| Initial setup | installation.md |
| Store patterns | store-patterns.md |
| SSR/Hydration | hydration.md |
| Middleware | middleware.md |
| Next.js App Router | nextjs-integration.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 |
|---|---|---|
| Global stores in App Router | Request sharing between users | Context-based stores |
| Zustand in Server Components | No React hooks in RSC | Fetch data directly |
| 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>()() |
What ships with it: 12 files
57.1 KB alongside SKILL.md
references/
- auto-selectors.md4.1 KB
- hydration.md5.4 KB
- installation.md2.3 KB
- middleware.md5.2 KB
- migration-v5.md3.9 KB
- nextjs-integration.md4.8 KB
- reset-state.md4.8 KB
- slices.md5.0 KB
- store-patterns.md5.1 KB
- subscribe-api.md5.3 KB
- testing.md5.1 KB
- typescript.md6.3 KB