DEV Community

Alex Spinov
Alex Spinov

Posted on

Zustand Has a Free State Manager That Replaces Redux — No Boilerplate, No Providers, 1KB

The Redux Problem

Redux: create store, create slices, write reducers, dispatch actions, connect with useSelector. 50+ lines of boilerplate for a counter.

Zustand is a 1KB state manager. Create a store in 5 lines. Use it anywhere. No Provider wrapper.

What Zustand Gives You

Create a Store

import { create } from 'zustand';

interface BearStore {
  bears: number;
  increase: () => void;
  decrease: () => void;
  reset: () => void;
}

const useBearStore = create<BearStore>((set) => ({
  bears: 0,
  increase: () => set((state) => ({ bears: state.bears + 1 })),
  decrease: () => set((state) => ({ bears: state.bears - 1 })),
  reset: () => set({ bears: 0 }),
}));
Enter fullscreen mode Exit fullscreen mode

Use It

function BearCounter() {
  const bears = useBearStore((state) => state.bears);
  return <h1>{bears} bears</h1>;
}

function Controls() {
  const increase = useBearStore((state) => state.increase);
  return <button onClick={increase}>Add bear</button>;
}
Enter fullscreen mode Exit fullscreen mode

No Provider. No Context. Just import and use.

Async Actions

const useStore = create((set) => ({
  users: [],
  loading: false,
  fetchUsers: async () => {
    set({ loading: true });
    const users = await fetch('/api/users').then(r => r.json());
    set({ users, loading: false });
  },
}));
Enter fullscreen mode Exit fullscreen mode

Middleware

import { persist, devtools } from 'zustand/middleware';

const useStore = create(
  devtools(
    persist(
      (set) => ({
        theme: 'light',
        setTheme: (theme) => set({ theme }),
      }),
      { name: 'app-settings' }
    )
  )
);
Enter fullscreen mode Exit fullscreen mode

Persist to localStorage. DevTools integration. All via middleware.

Slices Pattern

const createAuthSlice = (set) => ({
  user: null,
  login: (user) => set({ user }),
  logout: () => set({ user: null }),
});

const createCartSlice = (set) => ({
  items: [],
  addItem: (item) => set((state) => ({ items: [...state.items, item] })),
});

const useStore = create((...a) => ({
  ...createAuthSlice(...a),
  ...createCartSlice(...a),
}));
Enter fullscreen mode Exit fullscreen mode

Bundle Size

Library Size
Redux + RTK 11KB
MobX 15KB
Zustand 1.1KB

Quick Start

npm install zustand
Enter fullscreen mode Exit fullscreen mode

Why This Matters

State management shouldn't require architecture decisions. Zustand is simple enough for a todo app and powerful enough for a production dashboard.


Managing data-heavy state? Check out my web scraping actors on Apify Store — structured data for your stores. For custom solutions, email spinov001@gmail.com.

Top comments (0)