What Zustand Does
- Global state — one store, many slices
- Selectors — subscribe to specific slices (avoids unnecessary renders)
- Middleware — persist, devtools, immer, subscribeWithSelector
- Vanilla support — usable outside React
- Transient updates — subscribe without rerendering
- Async actions — plain async functions in the store
Architecture
A store is a function returning state + actions. create() returns a React hook bound to that store. Selectors (useStore(s => s.slice)) prevent re-renders when unrelated state changes. No reducers, no dispatch.
Self-Hosting
Client library only. No server needed.
Key Features
- ~1KB gzipped
- No providers (works outside React tree)
- TypeScript-first
- Middleware: persist (localStorage), devtools (Redux DevTools), immer
- SSR-safe
- Transient subscriptions (
subscribeAPI) - Slices pattern for large stores
Comparison
| Library | Size | Boilerplate | DevTools | Providers |
|---|---|---|---|---|
| Zustand | ~1KB | Minimal | Yes | No |
| Redux Toolkit | ~13KB | Medium | Yes | Yes |
| Jotai | ~3KB | Atomic | Yes | Yes |
| Valtio | ~3KB | Mutable proxy | Yes | No |
| React Context | 0 | High | No | Yes |
FAQ
Q: How does it compare to Redux? A: Zustand has no reducers, no providers, and no action types. Code volume drops by 70%+. But Redux has a larger ecosystem (RTK Query, etc.).
Q: Does it support SSR? A: Yes. For Next.js, creating a new store per request is recommended to avoid cross-request pollution.
Q: How should I organize a large store?
A: Use the slices pattern: split the store into multiple createSlice functions by feature, then merge them in create().
Sources & Credits
- Docs: https://zustand-demo.pmnd.rs
- GitHub: https://github.com/pmndrs/zustand
- License: MIT