Zustand
A small, hook-based store with almost no ceremony.
What it is
Zustand is a small, fast, and scalable state management library for React. It provides a simple API to create global state stores with minimal boilerplate, using hooks for accessing and updating state.
Zustand allows you to create a store that holds your global state. Components can read from and write to the store using hooks. It supports derived state, middleware, and persistence without forcing a specific architecture.
- Licence
- MIT
- Best known for
- A working store in about five lines
When to use it
The question documentation cannot answer for you — because it cannot recommend something else.
Reach for it when
- You need shared client state and Redux feels disproportionate
- You want a store you can read outside React components as easily as inside
Look elsewhere when
- The state is really cached server data — use React Query or SWR
- Your team specifically wants Redux's enforced structure and action log
Installation
npm install zustandGetting started
The smallest useful thing you can do with it, and what each part means.
import create from 'zustand';
const useStore = create(set => ({
count: 0,
increment: () => set(state => ({ count: state.count + 1 })),
decrement: () => set(state => ({ count: state.count - 1 }))
}));function Counter() {
const { count, increment, decrement } = useStore();
return (
<div>
<button onClick={decrement}>-</button>
<span>{count}</span>
<button onClick={increment}>+</button>
</div>
);
}Advanced usage
Where the library earns its place over a simpler alternative.
const useStore = create(set => ({
count: 0,
double: () => set(state => ({ count: state.count * 2 }))
}));
const doubledCount = useStore(state => state.count * 2);import { persist } from 'zustand/middleware';
const useStore = create(persist(
set => ({ count: 0, increment: () => set(state => ({ count: state.count + 1 })) }),
{ name: 'counter-storage' }
));const useStore = create(set => ({
count: 0,
incrementBy: (n) => set(state => ({ count: state.count + n })),
reset: () => set({ count: 0 })
}));Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- State not updating in component
- Ensure you are using the hook returned by the store and not a stale reference. Destructure state inside the component.
- Performance issues with large state
- Split state into multiple smaller stores and select only needed slices with hooks.
- Persisted state not working
- Check that the `persist` middleware is correctly applied and browser localStorage is accessible.
Best practices
- Use small, focused stores for different concerns rather than one large global store.
- Leverage hooks to read only the parts of state needed by a component to avoid unnecessary re-renders.
- Use middleware like `persist` or `redux-devtools-extension` for debugging and persistence.
- Keep state updates immutable even though Zustand allows direct mutation in set functions.
- Encapsulate complex logic inside actions rather than inside components.
Alternatives
Comparable options, and the reason you would pick one over the other.
Background
Why it exists, and what it was reacting to.
Zustand was created by Jotai and React community contributors to offer an alternative to heavier state management libraries like Redux. It emphasizes simplicity, ease of use, and minimalistic design while being highly performant and flexible for both small and large applications.
