In Part 1 (opens in new tab) of this series, we explored React’s built-in tools like useState, useReducer and the Context API — which are often more powerful than people give them credit for.
But let’s be honest:
As your app grows, managing state with just hooks and Context can get... messy.
That’s where client-side state libraries come in — helping you organize, share, and scale your state across large applications without losing your sanity.
What Is “Client-Side State”?
Before we dive into libraries, let’s quickly define what we mean by client-side state:
- It lives in the browser, not on a server.
- It’s usually tied to UI interactions and user context.
- Things like:
- Selected filters
- Auth status
- Modal open/close
- Sidebar collapse state
- Theme preferences
Popular Client-Side State Libraries in 2025
Let’s look at some of the most widely used tools — from the old guard (Redux) to newer, simpler libraries like Zustand and Recoil.
The state management OG.
Redux has been around for years, and while it got a bad rep for being “boilerplate-heavy,” that all changed with Redux Toolkit.
Core Concepts (quick refresher):
- A single source of truth for your app’s state
- Reducers to define how state changes
- Actions to describe those changes
- Selectors to read state in components
Why Redux Toolkit (RTK) makes Redux better:
- createSlice() to bundle reducers and actions together
- createAsyncThunk() to handle async calls
- Pre-configured store setup with good defaults
- Built-in dev tools + TypeScript support
When to use Redux/RTK:
- Large apps with complex, deeply nested state
- You need time-travel debugging, middleware, or advanced dev tools
- Your team is already familiar with Redux
Downsides:
- Still more setup than newer libraries
- Can be overkill for small/medium apps
Zustand — "Global state without the fuss"
Zustand (German for "state") is a tiny but powerful library from the creators of Jotai and React Spring.
Why devs love it:
- Simple API: no boilerplate, no context provider
- Tiny bundle size (~1kb)
- Works with any React app (doesn’t depend on Context)
- Reactive without extra re-renders
import { create } from 'zustand';
const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}));
When to use Zustand:
- Medium to large apps with shared UI state
- You want simplicity + performance
- You’re tired of boilerplate but still need global state
Downsides:
- No built-in dev tools like Redux (though some exist)
- Not opinionated — you have to define structure yourself
Recoil - State as atoms
Recoil is Facebook’s experimental state management library that treats state as a graph of small pieces (called atoms).
Core Concepts:
- Atoms: Units of state (like
useState, but global) - Selectors: Derived state or computed values
- Fine-grained updates = better performance
const countAtom = atom({ key: 'count', default: 0 });
function Counter() {
const [count, setCount] = useRecoilState(countAtom);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
When to use Recoil:
- You have lots of small, independent pieces of state
- You want React-style API with global power
- You want granular control over what re-renders and when
Downsides:
- Still experimental (not “officially stable” yet)
- Limited community/tools compared to Redux
Jotai - Minimalist Recoil
Jotai (from the same team as Zustand) is like Recoil but even simpler.
- Also atom-based
- Less magic than Recoil
- Uses plain React primitives
- Very small (~1kb) and fast
const countAtom = atom(0);
function Counter() {
const [count, setCount] = useAtom(countAtom);
return <button onClick={() => setCount((c) => c + 1)}>{count}</button>;
}
When to use Jotai:
- You like the atom model, but want zero config
- You’re building a React-only app and want simplicity
How Do They Compare?
Here’s a quick breakdown (replacing a table):
Redux Toolkit
“It’s like using Microsoft Excel for a to-do list — powerful, but a bit much for small jobs.”
- Best for: Large apps, advanced tooling
- Pros: Predictable, battle-tested, async tools
- Cons: Still verbose, more setup
Zustand
“Feels like jotting things down on a sticky note — fast, effortless, gets the job done.”
- Best for: Simple & fast global state
- Pros: Tiny, fast, no boilerplate
- Cons: No structure or conventions
Recoil
"Imagine giving every piece of your UI its own little brain. That’s Recoil."
- Best for: Complex UI state with fine-grained reactivity
- Pros: Selectors, performance
- Cons: Experimental
Jotai
“Like Recoil, but stripped down. It's the IKEA version — minimalist, efficient, no frills.”
- Best for: Lightweight apps that still need atoms
- Pros: Simple, fast, minimal
- Cons: Less adoption than Zustand or Redux
TL;DR
- React’s built-in tools are solid — but when your state gets bigger, you’ll want a library.
- Redux Toolkit is still a powerhouse for large apps with lots of moving parts.
- Zustand is a favorite for its simplicity and power with minimal setup.
- Recoil and Jotai offer atomic, fine-grained control — great for UI-heavy apps.
- Choose based on your app’s needs, not just popularity.
React’s built-in tools work great — until they don’t
Up Next: Part 3 — Server State & Hybrid Patterns
In Part 3, we’ll explore React Query, SWR, and how to combine client and server state in a clean, scalable way.