The frontend state management landscape has evolved dramatically beyond Redux's reducer-first patterns. Modern libraries prioritize minimal boilerplate, fine-grained reactivity, and clear separation between server state (API data) and client state (UI toggles, selections). Lightweight solutions like Zustand (~3KB) compete with atomic approaches (Jotai, Recoil) and observable patterns (MobX, Valtio), while state machines (XState) formalize complex flows explicitly. Understanding each tool's reactivity model—whether immutable updates, proxy-based mutations, or signals—determines not only bundle size but also render behavior, concurrent mode compatibility, and whether you're fighting or flowing with your framework's architecture.
What This Cheat Sheet Covers
This topic spans 12 focused tables and 41 indexed concepts. Below is a complete table-by-table outline of this topic, spanning foundational concepts through advanced details.
Table 1: Lightweight Immutable Stores
Lightweight immutable stores use minimal APIs and reducer-free updates while maintaining immutability. These libraries colocate state declaration and update logic without middleware layers, making them ideal for modern React hooks patterns where simplicity and bundle size matter more than time-travel debugging.
| Library | Example | Description |
|---|---|---|
const useStore = create((set) => ({ count: 0, inc: () => set((s) => ({ count: s.count + 1 }))})) | • Hooks-first store (3KB) with no providers needed • direct state mutations inside set for DX simplicity while maintaining immutability internally• supports middleware (persist, devtools, immer). | |
import { atom } from 'nanostores'const $count = atom(0)$count.set($count.get() + 1) | • Tiny (286 bytes) framework-agnostic atomic stores with get() and set() API• no JSX-specific hooks • works in React, Vue, Svelte, Preact, Angular • ideal for multi-framework projects |