React’s built-in useState and useContext work great — until they don’t.
When your app scales, managing shared and deeply nested state becomes messy. That’s where atomic state management libraries come in.
In this post, we’ll explore three of the most popular libraries that embrace this model:
Let’s dive into how each works, their strengths, and which might fit your project best.
🧩 What is Atomic State Management?
Traditional state managers like Redux rely on a single global store — all data flows through a central structure.
Atomic state flips that idea.
Instead of one big store, your state is composed of independent atoms — small, isolated units of state that can be subscribed to directly.
Each atom updates only the components that use it — no global re-renders, no boilerplate, no reducers.
⚡ Zustand: Minimal and Fast
Zustand is a tiny, unopinionated state manager that feels like using plain React hooks — but with superpowers.
npm install zustand
Example
import { create } from 'zustand'
const useStore = create((set) => ({
count: 0,
increase: () => set((state) => ({ count: state.count + 1 })),
}))
function Counter() {
const { count, increase } = useStore()
return (
<button onClick={increase}>
Count: {count}
</button>
)
}
✅ Pros
- Minimal API (~1KB gzipped)
- Direct, predictable mutations
- Excellent for medium-to-large apps
- Works outside React (e.g. vanilla JS)
⚠️ Cons
- No built-in async or atom logic (you write it manually)
- Less declarative than Jotai/Recoil
🧬 Jotai: Primitives for React State
Jotai (which literally means “atom” in Japanese) provides atomic state primitives — tiny pieces of state managed independently.
npm install jotai
Example
import { atom, useAtom } from 'jotai'
const countAtom = atom(0)
function Counter() {
const [count, setCount] = useAtom(countAtom)
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
)
}
✅ Pros
- Simple mental model (like Recoil, but smaller)
- Derivable atoms (
atom(get => get(otherAtom) + 1)) - SSR-friendly
- Built on React’s native
useSyncExternalStore
⚠️ Cons
- Requires you to think atomically — might feel verbose for simple apps
- Lacks centralized debugging tools (yet)
🪶 Recoil: Facebook’s Take on Atoms and Selectors
Recoil was built by Facebook to solve React’s global state challenges.
It introduces atoms and selectors for derived data.
npm install recoil
Example
import { atom, selector, useRecoilState, useRecoilValue } from 'recoil'
const countAtom = atom({
key: 'count',
default: 0,
})
const doubleCount = selector({
key: 'doubleCount',
get: ({ get }) => get(countAtom) * 2,
})
function Counter() {
const [count, setCount] = useRecoilState(countAtom)
const double = useRecoilValue(doubleCount)
return (
<div>
<p>Count: {count}</p>
<p>Double: {double}</p>
<button onClick={() => setCount(count + 1)}>Increase</button>
</div>
)
}
✅ Pros
- Mature, production-ready (used at Meta)
- Powerful selectors (derived/computed state)
- Great dev tools and debugging
⚠️ Cons
- Larger bundle (~15KB)
- Requires
RecoilRootprovider - Still React-only (no vanilla JS usage)
⚖️ When to Choose What
| Library | Best For | API Style | Size | Ecosystem |
|---|---|---|---|---|
| Zustand | Scalable apps needing minimal setup | Mutations | ~1KB | Strong (PMNDRS) |
| Jotai | Declarative atomic apps | Primitives | ~3KB | Moderate |
| Recoil | Large apps needing selectors and tooling | Atoms + Selectors | ~15KB | Mature |
🧠 TL;DR
- Zustand → If you want simplicity and speed.
- Jotai → If you want minimalism with atomic reactivity.
- Recoil → If you want structure, selectors, and dev tools.
All three are excellent — the “best” choice depends on your project’s scale and mental model preference.
💬 Final Thoughts
Atomic state management isn’t just a buzzword — it’s a mindset shift.
It helps React apps stay predictable, performant, and modular as they grow.
If you haven’t tried these yet:
- Start with Zustand to grasp the basics.
- Move to Jotai or Recoil for more reactive patterns.
Happy coding! ⚛️✨
If you enjoyed this, follow me for more deep dives on modern React state patterns!
👉 @taronva
Top comments (0)