Zustand
Master Zustand — the lightweight, modern state management library that most teams should use instead of Redux. Learn store design, selectors, persistence, and enterprise patterns.
Last reviewed: January 2025
🔍 What Is It?
Zustand provides a simple API to create a global state store:
const useStore = create<State>((set, get) => ({
count: 0,
increment: () => set(state => ({ count: state.count + 1 })),
reset: () => set({ count: 0 }),
}));- →
create— creates a hook that components use to subscribe to the store - →
set— updates state (shallow merges by default, like setState) - →
get— reads current state inside actions (useful for derived logic) - →Selectors —
useStore(state => state.count)subscribes to only the count field; the component only re-renders when count changes
🎯 Why Do We Need It?
Context API causes all consumers to re-render when the value changes. Redux requires actions, action types, reducers, and selectors for every piece of state. Zustand sits in the sweet spot:
- →No boilerplate — define state and actions in one function
- →Selector-based subscriptions — components only re-render when their specific slice changes
- →No Provider needed — the store is a module-level singleton
- →Works outside React — actions can be called from anywhere (event handlers, utility functions, other stores)
- →1KB — negligible bundle impact
🏗️ What Happens in Real Projects?
Zustand is ideal for:
- →Shopping cart — items, quantities, totals, add/remove actions
- →UI state — sidebar open/closed, active modal, selected rows in a table
- →Filter state — search query, selected filters, sort order shared across a page
- →User preferences — theme, language, notification settings (with persist middleware)
- →Multi-step forms — form data persisted across steps
⚙️ How It Works
Zustand uses a pub/sub model. The store is a JavaScript object. When you call set, Zustand:
- Merges the new state shallowly
- Notifies all subscribers
- Each subscriber runs its selector function
- If the selected value changed (by reference), the component re-renders
No Provider:
Unlike Context, Zustand stores are module-level singletons. You import the hook directly. This makes it simpler to use but also means all instances of the app share the same store (relevant for SSR/testing).
💻 Example
Zustand in a Real Application — Store definition, selectors, async actions, and persistence.
🤔 Common Confusions
❓ Does Zustand need a Provider?
No. Zustand stores are module-level singletons. You just import the hook and use it anywhere. This is simpler than Context/Redux but means all app instances share the same store — relevant for SSR (use createStore instead of create for SSR-safe stores) and testing (reset the store between tests).
❓ How do I prevent unnecessary re-renders with Zustand?
Use selectors: useStore(state => state.count) instead of useStore(). With a selector, the component only re-renders when the selected value changes. Without a selector, the component re-renders on any store update. For objects, use the shallow equality helper: useStore(state => state.user, shallow).
❓ Should I put everything in one Zustand store?
No. Create separate stores per concern: useCartStore, usePolicyStore, useUIStore. This keeps stores focused, easier to test, and prevents unrelated updates from triggering re-renders across unrelated consumers.
🚨 Common Production Issues
**Re-renders without selectors** — useStore() without a selector subscribes to the entire store. Any update re-renders the component. Always use selectors.
**Object selector instability** — useStore(state => ({ a: state.a, b: state.b })) creates a new object every render. Fix: use the shallow import from zustand/shallow.
**SSR issues** — Module-level stores cause hydration mismatches in Next.js. Use createStore with a React context wrapper for SSR-safe Zustand.
**Testing** — Zustand stores persist between tests. Reset the store in beforeEach: useStore.setState(initialState).
✅ Best Practices
Always use selectors to subscribe to specific slices of state
Use shallow from zustand/shallow for object selectors
Separate stores by domain concern — not one giant store
Use the persist middleware for state that should survive page refreshes
Reset stores in test beforeEach hooks
For SSR (Next.js), use the context pattern for Zustand stores
Keep actions close to the state they modify — define them inside the store
🏛️ Architect's Note
Zustand is the right default choice for state management in 2024. It is small, simple, and powerful enough for the vast majority of React applications. The pattern I use in every project: Context for dependency injection (auth, theme), Zustand for application state (cart, filters, UI), React Query for server state (API data). This three-layer approach covers every state management need without the overhead of Redux.
💬 Frequently Asked Questions
🎯 Key Takeaways
🔗 Related Topics
🎯 Practice this topic in interviews
↗ Where this topic fits
React Technology Guide
Return to the React learning hub.
Frontend Engineer Career Path
A beginner-friendly journey through web foundations, React, production frontend engineering, and interview preparation.
Python Developer Career Path
A practical route through Python fundamentals, automation, backend basics, testing, projects, interview preparation, and career growth.
Sources
Sources / References
Use these React references to verify the concept in official docs and continue into the most relevant SplashRide pages.
Official documentation
Related SplashRide pages
SplashRide React learning path
Browse the full React topic collection and learning order on SplashRide.
React Interview Prep
Practice React interview questions and scenario-based answers.
Frontend Engineer Career Path
A beginner-friendly journey through web foundations, React, production frontend engineering, and interview preparation.
Python Developer Career Path
A practical route through Python fundamentals, automation, backend basics, testing, projects, interview preparation, and career growth.
Context API
Master React Context — the built-in solution for sharing state across the component tree without prop drilling. Learn when to use it, when not to, and how senior engineers implement it in production.
Redux Toolkit
Master Redux Toolkit — the modern, opinionated way to write Redux. Learn slices, thunks, RTK Query, and when Redux is actually the right choice for enterprise React applications.