// LOADING
// LOADING
// LOADING_ARTICLE
Zustand is a small, fast, and scalable state management library for React.
It is:
You can think of Zustand as a simpler alternative to Redux — but with modern React in mind.
bashnpm install zustand # or yarn add zustand
At the heart of Zustand is a store, which holds your state and actions.
Here is the simplest example:
jsimport create from "zustand"; const useStore = create((set) => ({ count: 0, increase: () => set((state) => ({ count: state.count + 1 })), decrease: () => set((state) => ({ count: state.count - 1 })), }));
You can now use this store in any component:
jsfunction Counter() { const { count, increase, decrease } = useStore(); return ( <div> <h1>{count}</h1> <button onClick={increase}>+</button> <button onClick={decrease}>-</button> </div> ); }
✅ No provider ✅ No reducers ✅ No action types ✅ No dispatch
Just simple, clean state.
jsconst useTodoStore = create((set) => ({ todos: [], addTodo: (text) => set((state) => ({ todos: [...state.todos, { id: Date.now(), text, done: false }], })), toggleTodo: (id) => set((state) => ({ todos: state.todos.map((todo) => todo.id === id ? { ...todo, done: !todo.done } : todo ), })), removeTodo: (id) => set((state) => ({ todos: state.todos.filter((todo) => todo.id !== id), })), }));
jsfunction TodoApp() { const { todos, addTodo, toggleTodo, removeTodo } = useTodoStore(); const [text, setText] = useState(""); return ( <div> <input value={text} onChange={(e) => setText(e.target.value)} placeholder="Add todo..." /> <button onClick={() => { addTodo(text); setText(""); }} > Add </button> <ul> {todos.map((todo) => ( <li key={todo.id}> <span style={{ textDecoration: todo.done ? "line-through" : "none" }} onClick={() => toggleTodo(todo.id)} > {todo.text} </span> <button onClick={() => removeTodo(todo.id)}>❌</button> </li> ))} </ul> </div> ); }
jsconst useAuthStore = create((set) => ({ user: null, login: (userData) => set({ user: userData }), logout: () => set({ user: null }), }));
jsfunction Profile() { const { user, logout } = useAuthStore(); if (!user) return <h1>Please log in</h1>; return ( <div> <h1>Welcome, {user.name}</h1> <button onClick={logout}>Logout</button> </div> ); }
Instead of:
jsconst { user, logout } = useAuthStore();
Do this:
jsconst user = useAuthStore((state) => state.user);
This ensures your component only re-renders when user changes.
jsimport { persist } from "zustand/middleware"; const useSettingsStore = create( persist( (set) => ({ theme: "light", setTheme: (theme) => set({ theme }), }), { name: "settings-storage" } ) );
Now your theme will persist even after refresh.
| Feature | Redux | Zustand | | ---------------- | ----- | --------- | | Boilerplate | High | Very Low | | Learning Curve | Steep | Easy | | Performance | Good | Excellent | | DevTools | Great | Available | | Setup Time | Slow | Fast | | React Native | Yes | Yes | | Providers Needed | Yes | No |
👉 If you're starting a new project in 2024, Zustand is often a better choice than Redux unless you need Redux ecosystem tools.
Example of multiple stores:
jsconst useCartStore = create((set) => ({ cart: [] })); const useUIStore = create((set) => ({ darkMode: false }));
You might not need Zustand if:
useStateZustand is:
✔ Simple ✔ Fast ✔ Scalable ✔ Modern ✔ Developer-friendly
If you're building a new React app in 2026, Zustand is one of the best choices for state management.