Redux vs Zustand: Simplifying React State Management
When less is more: Why developers are switching from Redux to Zustand
When I first started working with states in React, I defaulted to Redux mostly because that’s what everyone around me was using.
But the deeper I got into it, the more I started asking myself: why does toggling a simple value require so much setup?
Reducers, action types, dispatch… it all felt like overkill especially for smaller apps or isolated component state.
Then I came across Zustand, and it just clicked. ⚡
The Redux Approach
Redux is powerful, battle-tested, and widely adopted. But that power comes with complexity:
import { createStore } from 'redux';
const counterReducer = (state = 0, action) => {
if (action.type === ‘INCREMENT’) {
return state + 1;
}
return state;
};
const store = createStore(counterReducer);
store.dispatch({ type: ‘INCREMENT’ });
With Redux, you need to understand several concepts before getting started: actions, reducers, stores, and dispatch. There’s a lot of boilerplate even for simple operations.
The Zustand Simplicity
Zustand strips away the complexity while maintaining the power:
import { create } from 'zustand';
const useStore = create((set) => ({
count: 0,
increment: () => set((
count: state.count + 1)
)
}));
Notice what’s missing?
- •No context providers wrapping your app
- •No reducers to manage
- •No action types or dispatch calls
Using the Store
Redux
import { useSelector, useDispatch } from 'react-redux';
function Counter() {
const count = useSelector(state => state);
const dispatch = useDispatch();
return (
<div>
Count: {count}
<button onClick={() =>
dispatch({ type: ‘INCREMENT’ })
}>+1</button>
</div>
);
}
Zustand
function Counter() {
const count = useStore(state => state.count);
const increment = useStore(state =>
state.increment
);
return (
<div>
Count: {count}
<button onClick={increment}>+1</button>
</div>
);
}
With Zustand, you can directly access not just state values but also actions from your store with a clean, straightforward API.
Code Comparison
REDUX
import { createStore } from 'redux';
const counterReducer = (state = 0, action) => {
if (action.type ===’INCREMENT’) {
return state + 1;
}
return state;
};
const store = createStore(counterReducer);
store.dispatch({ type: ‘INCREMENT’ });
ZUSTAND
import { create } from 'zustand';
const useStore = create((set) => ({
count: 0,
increment: () => set((
count: state.count + 1)
)
}));
Key Benefits of Zustand
Minimal API
Just a few lines of code, and everything works cleanly and predictably.
TypeScript First
Excellent TypeScript support with minimal configuration required.
No Provider Needed
No need to wrap your app with providers stores are accessible anywhere.
Middleware Support
Supports middleware for persistence, devtools, and more when needed.
When to Choose What
Stick with Redux if:
- Your app has complex state logic that benefits from middleware-heavy processing
- You need time-travel debugging and robust dev tools
- Your team is already familiar with Redux patterns
- You’re working on a large enterprise application with many developers
Try Zustand if:
- You’re tired of Redux boilerplate for simple state changes
- You want fast setup with minimal configuration
- You’re building a smaller to medium-sized application
- You prefer a more straightforward, hooks-based API
Migrating from Redux to Zustand
If you’re considering switching from Redux to Zustand, here’s a simplified migration path:
- Start small: Convert one slice of your Redux store to Zustand
- Identify action creators: Convert them to simple functions in your Zustand store
- Adapt selectors: Update your component selectors to use Zustand’s hook pattern
- Gradually expand: Incrementally convert more parts of your app as you become comfortable
Pro Tip: You can use both Redux and Zustand side by side during migration. This allows for an incremental approach without a complete rewrite.
Final Thoughts
It plays nicely with TypeScript and scales effortlessly when your app grows. These days, Zustand is my go-to for local state, no boilerplate, no headaches.
If Redux feels too heavy for what you’re building, give Zustand a try. I wish I had sooner.
Curious what’s your go-to for state management in React/Next these days? 💬