Why Zustand Works Better Than Redux Toolkit in React

SINCE 2013

Different Thinking Styles
How to Pick the Perfect Thinking Style: Finding What Works for You!
21st July 2025
AI tools in Automation Testing
Best AI Testing Tools for Test Automation in 2025
23rd July 2025
Different Thinking Styles
How to Pick the Perfect Thinking Style: Finding What Works for You!
21st July 2025
AI tools in Automation Testing
Best AI Testing Tools for Test Automation in 2025
23rd July 2025

As a developer who’s faced a wide range of frontend challenges, choosing the right state management solution became crucial for both my efficiency and peace of mind. Over the years, I’ve experimented with various tools—starting with the classic Redux, moving through the Context API, and eventually adopting Redux Toolkit. While Redux Toolkit was a notable improvement over its predecessor, everything changed when I discovered Zustand. It immediately clicked with me. In this post, I’ll share my personal journey and explain why Zustand ultimately became my go-to over Redux Toolkit.

First Encounter with Redux Toolkit

When I first used Redux several years ago, it felt verbose, cumbersome, and overly complex. The boilerplate was overwhelming — reducers, actions, dispatchers, and middlewares were a headache. So when Redux Toolkit emerged, promising to simplify Redux, I eagerly adopted it in my workflow.

Redux Toolkit streamlined much of Redux’s boilerplate, making actions and reducers cleaner and easier to manage:

import { createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
name: 'counter',
initialState: 0,
increment: state => state + 1,
decrement: state => state - 1,
}
});

Redux Toolkit was a breath of fresh air compared to the original Redux workflow. It reduced boilerplate significantly, making my code cleaner and less error-prone.

But the Complexity Remained

Despite improvements, Redux Toolkit still required boilerplate, especially when handling asynchronous data and middleware. My project became increasingly complex, with multiple slices, selectors, actions, and reducers. Debugging grew cumbersome, especially as the app scaled.

It was at this point that I began searching for alternatives, hoping for simplicity without sacrificing functionality.

Discovering Zustand

I first stumbled upon Zustand during a React meet-up when a colleague enthusiastically introduced it. The concept was instantly appealing: a minimalistic, unopinionated state management solution using hooks. Zustand promised simplicity without excessive boilerplate.

The simplicity:

import create from 'zustand';

const useStore = create(set => ({
count: 0,
increment: () => set(state => ({ count: state.count + 1 })),
decrement: () => set(state => ({ count: state.count - 1 })),
}));

No actions, reducers, or slices were necessary — just clean, concise state management.

Compared to Redux Toolkit, Zustand made asynchronous data handling simpler and quicker to set up.

Creating multiple slices

Configuring Thunks and middleware

Connecting React components via selectors and useDispatch

After shifting to Zustand, the code became cleaner:

import create from 'zustand';
import axios from 'axios';

const useNewStore = create((set) => ({
  locations: [],
  loading: false,
  error: null,  fetchLocations: async () => {
    set({ loading: true });
    try {
      const res = await axios.get('/locations');
      set({ locations: res.data, loading: false });
    } catch (error) {
      set({ error, loading: false });
    }
  },
}));

Why Zustand Stands Out

1. Minimal Boilerplate

Redux Toolkit, though simplified, still requires managing actions, slices, and reducers. Zustand drastically reduces this complexity:

  • Redux Toolkit Example: Multiple files and folders for slices, reducers, and store configuration.
  • Zustand: One straightforward setup per store.

2. Less Cognitive Overhead

With Zustand, you spend less time managing state and more time building your features. The clarity it brings to your codebase improves productivity and team collaboration significantly.

3. Better Performance by Default

Zustand updates components precisely when the relevant state changes, without manual optimization:

const count = useStore(state => state.count);

4. Easy Integration with Middleware

Integrating Zustand with middleware like persistency, logging, or Immer for immutability is straightforward:

import create from 'zustand';
import { devtools } from 'zustand/middleware';

const useStore = create(devtools(set => ({
count: 0,
increment: () => set(state => ({ count: state.count + 1 })),
})));

Zustand’s middleware support effortlessly adds powerful debugging capabilities without overhead.

More Info…
Related Blog…