Overview

Use Zustand for new React work. It is 1 KB, uses one hook, and gets out of the way. Use Redux Toolkit (RTK) only when the team already runs a large Redux codebase, needs Redux DevTools’ time-travel debugging across many engineers, or wants RTK Query bundled with the state library. The 2026 default for client state is Zustand; Redux is the niche pick now. See react-state-management for the upstream rule set.

When Zustand wins

Zustand is the right pick for nearly every new React app that needs client state beyond useState.

  • API surface: create((set) => ({ count: 0, inc: () => set((s) => ({ count: s.count + 1 })) })) is the whole library. New contributors are productive in 20 minutes.
  • No provider: stores are plain modules. No <Provider> wrapping App, no boilerplate context, no nested store provider trees.
  • Bundle: 1 KB gzipped. Redux Toolkit is 12 to 15 KB plus React-Redux bindings. On a content app with one store, the gap matters.
  • Selectors with referential stability: useStore((s) => s.user) re-renders only when user changes. No reselect, no memoization plumbing.
  • Server-state stays out: Zustand does not pretend to fetch data. Pair it with TanStack Query or SWR; see tanstack-query-vs-swr.
  • Middleware when needed: persist, devtools, immer, subscribeWithSelector. Each is opt-in.
  • Works with React Server Components: stores are client-side; you instantiate per-request via a provider only when the app needs SSR with per-user state.

When Redux wins

Redux Toolkit is the right pick in three concrete cases. Outside them, the choice is Zustand.

  • Existing Redux codebase past 50k LoC with a team that knows the patterns. Rewriting to Zustand is rarely the highest-value engineering work.
  • Time-travel debugging is a real workflow on the team: Redux DevTools’ action log, replay, and import/export of state are unmatched. Useful on complex apps with a QA team or designers reproducing bugs.
  • RTK Query is the data layer. RTK Query couples server-state caching to the Redux store with code generation from OpenAPI. If the team committed to it, swapping to TanStack Query plus Zustand is a meaningful migration.
  • Large-team discipline: 30-plus engineers benefit from the enforced action and reducer shape. Zustand’s freedom is a footgun at that scale unless the team writes its own conventions.
  • Strict event sourcing or audit trail requirements where every state change is a named action. Zustand can do this but does not enforce it.

Trade-offs at a glance

DimensionZustandRedux Toolkit
Bundle (gzipped)1 KB12 to 15 KB plus React-Redux
APIOne hook, plain modulesSlices, reducers, actions, thunks
Provider neededOnly for SSR per-request storesAlways (<Provider store={store}>)
BoilerplateMinimalSlim with RTK; still more than Zustand
SelectorsBuilt-in equality, no memoization neededcreateSelector for derived state
AsyncPlain functions in actionscreateAsyncThunk or RTK Query
Data fetchingExternal (TanStack Query, SWR)RTK Query bundled
DevToolsBrowser extension via middlewareFirst-class time-travel and replay
Hiring familiarityGrowing; default in new React workHigh; legacy in many enterprises
Cross-frameworkReact focus; React Native worksReact-Redux, Vue-Redux, others
TypeScriptExcellent inferenceGood; more explicit types
Sweet spotNew apps; small to medium teamsLarge legacy fleets; RTK Query users

Migration cost

Redux-to-Zustand is the common direction and usually pays back inside a quarter. The reverse is rare.

  • Redux to Zustand: port slice by slice. Each Redux slice becomes a Zustand store; selectors map one-to-one. Replace dispatched actions with store methods. Plan one engineer-week per 10 slices. The hard part is component updates, which a codemod covers for roughly 60 percent.
  • Redux Thunk or Saga to Zustand: rewrite async logic as plain functions in the store. Saga’s effect helpers do not map cleanly; budget extra time if the app uses them heavily.
  • RTK Query to TanStack Query: orthogonal swap, well-trodden. Plan one engineer-day per 20 endpoints.
  • Cheaper path: keep Redux for the legacy area, build new features in Zustand. Two stores coexist; React does not care.

Recommendation

  • New React app: Zustand. No exceptions worth listing for greenfield work.
  • Pair with TanStack Query for server state; see tanstack-query-vs-swr.
  • Existing Redux Toolkit app, no friction: stay. Rewriting state libraries rarely beats shipping features.
  • Existing classic Redux app (pre-RTK): migrate to Zustand on the next feature touching that area; do not big-bang rewrite.
  • App that genuinely uses Redux DevTools’ time-travel daily: Redux Toolkit.
  • Library author shipping reusable hooks: Zustand. Smaller surface area imposes less on consumers.
  • See react-state-management for the upstream “where does state live” decision.