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.

1

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.

2

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
3

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.

4

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)
)
}));

5

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.

6

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:

  1. Start small: Convert one slice of your Redux store to Zustand
  2. Identify action creators: Convert them to simple functions in your Zustand store
  3. Adapt selectors: Update your component selectors to use Zustand’s hook pattern
  4. 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? 💬

Leave a Comment

Your email address will not be published. Required fields are marked *