Introduction
Managing global state in React can become challenging as your application grows. While React’s built-in state (useState, useReducer, and context) works well for simple cases, it often becomes difficult to handle complex and deeply shared state across multiple components.
To solve this, lightweight state management libraries like Zustand and Jotai offer simple, scalable, and high-performance ways to manage global state with minimal code.
In this article, you’ll learn how Zustand and Jotai work, how to use them in real-world React applications, and how to decide which one fits your needs.
Why Not Just Use React Context?
React Context is useful but has limitations:
Causes unnecessary re-renders when state changes
Not ideal for large or deeply nested state
Harder to scale in big apps
Zustand and Jotai solve these issues with:
Better performance
Cleaner global state logic
Minimal boilerplate
What Is Zustand?
Zustand is a small, fast, and scalable state management library.
Key Features
Extremely simple API
No reducers or actions required
Global store with minimal code
Selectors to prevent unnecessary re-renders
Great for complex apps
Install Zustand
npm install zustand
Creating a Store in Zustand
Example Store
import { create } from 'zustand';
const useUserStore = create((set) => ({
user: null,
setUser: (data) => set({ user: data }),
clearUser: () => set({ user: null })
}));
Using the Store in a Component
function Profile() {
const user = useUserStore((state) => state.user);
const setUser = useUserStore((state) => state.setUser);
return (
<div>
<p>User: {user?.name ?? 'No user'}</p>
<button onClick={() => setUser({ name: 'Alex' })}>Login</button>
</div>
);
}
Why Zustand Works Well
Only subscribed components re-render
Clean and intuitive store structure
Handling Complex or Nested State with Zustand
Zustand makes complex state easy.
Example
const useCartStore = create((set) => ({
cart: [],
addItem: (item) => set((state) => ({ cart: [...state.cart, item] })),
removeItem: (id) => set((state) => ({ cart: state.cart.filter((i) => i.id !== id) }))
}));
Advantages
Immutable updates handled manually but cleanly
Supports async logic directly (no thunks needed)
Async State Logic in Zustand
Example Fetching Data
const useProductStore = create((set) => ({
products: [],
fetchProducts: async () => {
const res = await fetch('/api/products');
const data = await res.json();
set({ products: data });
}
}));
Why It’s Powerful
No extra middleware required
Async functions live directly inside the store
What Is Jotai?
Jotai is a minimalistic state management library based on atoms.
Key Features
Simple and flexible
Each piece of state is an atom
Fine-grained updates (only components using an atom re-render)
Great for shared UI state, forms, dynamic UIs
Install Jotai
npm install jotai
Creating Atoms in Jotai
Example Atom
import { atom, useAtom } from 'jotai';
const countAtom = atom(0);
Using an Atom
function Counter() {
const [count, setCount] = useAtom(countAtom);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>Increment</button>
</div>
);
}
Why Jotai Works Well
Atoms behave like
useState, but globallyZero boilerplate
Derived Atoms (Computed State in Jotai)
Jotai allows derived state based on other atoms.
Example
const priceAtom = atom(100);
const taxAtom = atom(10);
const totalAtom = atom((get) => get(priceAtom) + get(taxAtom));
Benefits
No reducers or complex selectors
Automatically updates when dependencies change
Async Atoms in Jotai
Jotai supports async atoms easily.
Example
const userAtom = atom(async () => {
const res = await fetch('/api/user');
return await res.json();
});
Why It’s Useful
Async logic integrated directly into state
No need for extra middleware
Zustand vs Jotai — Which Should You Use?
| Feature | Zustand | Jotai |
|---|---|---|
| Style | Single global store | Many small atoms |
| Best for | Complex and large apps | UI state, small to medium apps |
| Boilerplate | Minimal | Very minimal |
| Async logic | Built-in | Built-in |
| Performance | Excellent | Excellent |
| Learning curve | Very easy | Very easy |

Join the conversation! Your thoughts help the community grow.