Zustand Has a Free State Manager That Replaces Redux in 10 Lines
Source: Dev.to
Redux often requires actions, reducers, selectors, middleware, and dozens of lines of boilerplate even for a simple counter.
Zustand delivers the same capabilities in just a handful of lines—no actions, reducers, dispatchers, or Provider components required.
Minimal API
- Create a store in a few lines and use it anywhere.
- No boilerplate—no actions, reducers, or context providers.
- No
<Provider>wrapper—just import the hook. - TypeScript‑first—fully typed out of the box.
- Built‑in middleware support (persist, devtools, immer, subscriptions).
- ~1 KB gzipped (vs. ~30 KB for Redux Toolkit).
Installation
npm install zustandCounter Example
import { create } from 'zustand';
interface CounterStore {
count: number;
increment: () => void;
decrement: () => void;
reset: () => void;
}
const useCounter = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
reset: () => set({ count: 0 }),
}));
// Any component can import and use the store directly
function Counter() {
const count = useCounter((state) => state.count);
const increment = useCounter((state) => state.increment);
return (
<div>
Count: {count}
<button onClick={increment}>+</button>
</div>
);
}No <Provider> wrapper, no connect(), and no useSelector/useDispatch needed.
Auth Store with Persistence
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
interface User {
id: string;
name: string;
email: string;
}
interface AuthStore {
user: User | null;
token: string | null;
login: (email: string, password: string) => Promise;
logout: () => void;
isAuthenticated: () => boolean;
}
const useAuth = create()(
persist(
(set, get) => ({
user: null,
token: null,
login: async (email, password) => {
const { user, token } = await api.login(email, password);
set({ user, token });
},
logout: () => set({ user: null, token: null }),
isAuthenticated: () => get().token !== null,
}),
{ name: 'auth-storage' } // Persists to localStorage
)
);Todo Store (Async Actions)
import { create } from 'zustand';
interface Todo {
id: string;
title: string;
done: boolean;
}
interface TodoStore {
todos: Todo[];
loading: boolean;
fetchTodos: () => Promise;
addTodo: (title: string) => Promise;
toggleTodo: (id: string) => void;
}
const useTodos = create((set, get) => ({
todos: [],
loading: false,
fetchTodos: async () => {
set({ loading: true });
const todos = await api.getTodos();
set({ todos, loading: false });
},
addTodo: async (title) => {
const todo = await api.createTodo({ title });
set((state) => ({ todos: [...state.todos, todo] }));
},
toggleTodo: (id) => {
set((state) => ({
todos: state.todos.map((t) =>
t.id === id ? { ...t, done: !t.done } : t
),
}));
},
}));Async logic is written with plain async/await; no createAsyncThunk or extra middleware required.
Middleware Stack Example
import { create } from 'zustand';
import { devtools, persist, immer } from 'zustand/middleware';
interface Store {
items: string[];
addItem: (item: string) => void;
}
const useStore = create()(
devtools(
persist(
immer((set) => ({
items: [],
addItem: (item) =>
set((state) => {
state.items.push(item); // Immer makes this mutable update safe
}),
})),
{ name: 'my-store' }
)
)
);Combines Redux DevTools support, localStorage persistence, and Immer‑based mutable updates.
Feature Comparison
| Feature | Zustand | Redux Toolkit | Jotai | Recoil |
|---|---|---|---|---|
| Bundle size | ~1 KB | ~30 KB | ~3 KB | ~20 KB |
| Boilerplate | Minimal | Medium | Minimal | Medium |
| Provider needed | No | Yes | Yes | Yes |
| Async handling | Built‑in | createAsyncThunk | Built‑in | Selectors |
| DevTools | Built‑in | Plugin | Built‑in | Plugin |
| Learning curve | ~5 min | ~1 hour | ~15 min | ~30 min |
| TypeScript support | Excellent | Good | Excellent | Good |
TL;DR
Zustand is a state‑management solution for developers who want zero ceremony: a tiny bundle, no Provider, no reducers, and a simple, type‑safe API. If Redux feels heavyweight for your project, Zustand offers a lightweight alternative without sacrificing power.