Why I Stopped Using Redux (And What I Use Instead)← Blog6 min read
ReactState ManagementFrontend

Why I Stopped Using Redux (And What I Use Instead)

September 5, 2025 · 6 min read


Redux Isn't Bad. It's Just Heavy.

I used Redux for 4 years across 6 production apps. It's predictable, debuggable, and the DevTools are genuinely excellent. But every time I start a new project, I don't reach for it anymore.

Here's why — and what I use instead.

The Boilerplate Tax

A basic Redux setup for a feature requires: an action type constant, an action creator, a reducer case, a selector, a mapStateToProps, and a useDispatch call. For a shopping cart. Six files touched to add one piece of state.

Redux Toolkit helped significantly. But even with RTK, you're still writing more than you need to.

What I Migrated To

Zustand for Global UI State

For state that's genuinely global — current user, theme, modal visibility — Zustand is the answer.

const useStore = create<AppState>((set) => ({
  user: null,
  setUser: (user) => set({ user }),
  theme: "light",
  toggleTheme: () => set((s) => ({ theme: s.theme === "light" ? "dark" : "light" })),
}))

That's it. No actions. No reducers. No selectors. Just state and functions that update it. The bundle is 1.1kb.

TanStack Query for Server State

This was the bigger unlock. Most of what I was putting in Redux was server state — data fetched from an API. Redux handles that awkwardly. TanStack Query handles it brilliantly:

const { data: user, isLoading } = useQuery({
  queryKey: ["user", userId],
  queryFn: () => fetchUser(userId),
  staleTime: 5 * 60 * 1000,
})

Caching, background refetching, loading states, error states — all built in. I deleted ~40% of my Redux store the day I migrated.

Jotai for Local-ish State

When state is shared between a few components but not globally, Jotai's atom model is perfect. No Provider ceremony, just atoms:

const countAtom = atom(0)

function Counter() {
  const [count, setCount] = useAtom(countAtom)
  return <button onClick={() => setCount(c => c + 1)}>{count}</button>
}

When I'd Still Use Redux

Large teams where the strict action/reducer pattern prevents accidental state mutations. Apps with complex cross-cutting state logic where time-travel debugging actually matters. That's a narrow slice.

The Rule I Now Follow

  • Server data: TanStack Query
  • Global UI state: Zustand
  • Component-level shared state: Jotai or React Context
  • Local component state: useState

Redux doesn't appear on that list. Not because it's bad — but because each of the above tools does its specific job better.


← Back to Blog