Jotai vs Zustand
Both made by the same people. Both are better than Redux. The difference is atoms vs stores.
The short answer
Zustand over Jotai for most cases. Zustand is simpler to understand and works for 90% of state management needs.
- Pick Jotai if have lots of independent state atoms, need fine-grained re-render control, or love the atom/derived value pattern
- Pick Zustand if want the simplest possible state management, need to use state outside React, or just want something that works without thinking
- Also consider: If you're using TanStack Query for server state, you might not need either. Client state is often smaller than you think.
— Nice Pick, opinionated tool recommendations
Same Creator, Different Philosophy
Dai Shi (pmndrs) created both. Zustand is a top-down store. Jotai is bottom-up atoms. They solve the same problem differently.
Zustand: Create a store with state and actions. Subscribe to slices. Simple.
Jotai: Create atoms (individual pieces of state). Compose them. Derive computed values. More granular, more React-like.
Why Zustand is Easier
A Zustand store is just an object. create((set) => ({ count: 0, increment: () => set(s => ({ count: s.count + 1 })) })). Done.
No providers, no context, no wrappers. Use it anywhere. The API is 5 functions. You can learn it in 10 minutes.
It works outside React too. Use it in vanilla JS, in a worker, wherever.
When Jotai Shines
Jotai prevents unnecessary re-renders at a granular level. If component A uses atom X and component B uses atom Y, updating X never re-renders B. With Zustand, you need selectors to achieve this.
Async atoms are elegant. atom(async (get) => fetch(get(urlAtom))) — derived async state in one line.
For forms, complex UI state, or apps with many independent pieces of state, Jotai's atom model scales better.
Architecture: Single Store vs Primitive Atoms
Zustand is a single-store state machine. You define one store, subscribe to slices with selectors, and mutations are plain functions. Jotai scatters state into primitive atoms—each atom is its own unit. This sounds modular until you realize atoms need to be composed with derived atoms, creating a tangled dependency graph. In practice, Zustand’s single store is simpler to reason about: you open one file, see all state and actions. Jotai’s atom explosion forces you to jump between files to understand data flow. For a dashboard with 50+ state pieces, Zustand’s centralized store is a clear win. Jotai’s atom approach only pays off when state is truly independent, which is rare in real apps.
Performance: Manual Selectors vs Atom Dependency
Zustand gives you manual selectors—you pick exactly what you need, and the component only re-renders when that slice changes. Jotai uses automatic atom dependency tracking: each atom tracks its subscribers, and updates propagate through the atom graph. Sounds efficient, but in practice, Jotai’s fine-grained reactivity can lead to excessive re-renders when atoms are deeply nested or derived. Zustand’s selector approach is predictable: you control re-renders with precision. For a real-time stock ticker updating 10 fields per second, Zustand’s selectors let you skip irrelevant updates. Jotai’s automatic tracking may cause cascading updates across atoms, hurting performance. Zustand wins for performance-critical UIs.
Use Cases: E‑commerce Dashboards vs Derived State Apps
Zustand excels in e‑commerce, admin dashboards, and form-heavy apps where state is centralized and actions are straightforward. You have a cart, user profile, filters—all in one store. Jotai shines in apps with heavy derived state, like a spreadsheet or collaborative editor where state is computed from multiple sources. But for most web apps, Zustand’s single store is faster to build and maintain. Jotai’s derived atoms add complexity: you write getters and setters, and debugging becomes a maze. If you’re building a typical CRUD app, Zustand is the pragmatic choice. Jotai only justifies itself when state is inherently atomic and recomputation is cheap. For 90% of projects, pick Zustand.
Quick Comparison
| Factor | Jotai | Zustand |
|---|---|---|
| Mental Model | Atoms (bottom-up) | Store (top-down) |
| Learning Curve | Medium | Easy |
| Re-render Control | Automatic, granular | Selectors needed |
| Async State | Built-in (async atoms) | Manual |
| DevTools | Good | Good |
| Bundle Size | ~3KB | ~1KB |
| Outside React | React-focused | Works anywhere |
The Verdict
Use Jotai if: You have lots of independent state atoms, need fine-grained re-render control, or love the atom/derived value pattern.
Use Zustand if: You want the simplest possible state management, need to use state outside React, or just want something that works without thinking.
Consider: If you're using TanStack Query for server state, you might not need either. Client state is often smaller than you think.
Zustand is simpler to understand and works for 90% of state management needs. Jotai is more powerful for fine-grained reactivity but the mental model is harder to grok. Start with Zustand, reach for Jotai when you need it.
Related Comparisons
Disagree? nice@nicepick.dev