This episode reviews the evolution of React state management from prop drilling, the Context API, to boilerplate-heavy Redux, then the birth of Zustand by the pmndrs team in 2019. You will also understand the problems Zustand solves: no Provider, selective re-renders, and a size of around 1.2 KB gzipped.

Every tool is born from a problem. Before understanding Zustand technically, you need to understand the evolution map of state management in React: why the Context API existed, why Redux dominated for years, and why minimalist libraries like Zustand eventually emerged. Episode 1 is the history and background part that answers the most fundamental question: why do you need Zustand?
We will trace the evolution from prop drilling to the Context API, then boilerplate-heavy Redux, to the birth of Zustand by the pmndrs team in 2019. After that, we'll break down the three concrete problems Zustand solves: minimal boilerplate, selective re-renders, and a very small library size.
In React's early days, sharing state between components meant passing it down through props from parent to child — a pattern known as prop drilling. The deeper the component, the more prop layers had to pass through, making the code hard to maintain.
React introduced the Context API as the answer: a value is provided at a single point and read anywhere without passing props down. But Context has a weakness: every change to the context value re-renders all of its consumers, and Context is available above the provider that must wrap the application.
Redux emerged as a global state management solution with a strict pattern: a single store, actions, reducers, and selectors. Its strength is predictability and sophisticated devtools. However, in simple applications, Redux requires a lot of boilerplate: setting up the store, writing action types, action creators, and reducers for even one small feature.
const INCREMENT = 'INCREMENT'
function counterReducer(state = { count: 0 }, action) {
switch (action.type) {
case INCREMENT:
return { count: state.count + 1 }
default:
return state
}
}This comparison matters: switch (action.type) and the store configuration above are patterns that must be written over and over. Zustand removes this layer because an action is simply a function inside the store, with no separate action types.
In 2019, the pmndrs (Poimandres) team released Zustand — the German word for state. Behind it is Daishi Kato (dai-shi) as the main maintainer. Version 1 appeared in 2019, evolved through v2 and v3, v4 in 2022, to v5 in 2024, which is the basis of this series, with continuous improvements through 2026.
Zustand's philosophy is simple: a store is created with a single create() call, used directly as a hook, with no Provider, no reducer boilerplate, and no action types. This is the small revolution that led to its adoption by thousands of projects.
To give context to the version journey, here is Zustand's main release timeline:
This timeline explains why older documentation often uses the create form without double parentheses — that was the version 3 style. In this series we consistently use the newer v5 form.
You simply call create() in a store file and use the result in any component:
npm i zustandThere is no <Provider> wrapping your application, no HOC arrangement, and no separate store configuration. Stores and actions live in one place. npm i zustand adds the core library of about 1.2 KB gzipped to your application bundle — far smaller than a full Redux with react-redux.
The most important difference from Context: components using Zustand only re-render when the selected state slice changes, because Zustand is based on subscribe/notify with strict equality comparison. Context, by contrast, renders all consumers whenever the context value changes.
const count = useCounter((s) => s.count)
const name = useCounter((s) => s.user.name)With useCounter((s) => s.count), a change to s.user.name won't re-render a component that only reads count. We'll break down the technical subscribe/notify details in episode 2.
Zustand is built in layers: its core (zustand/vanilla) is pure JavaScript with no React dependency, and the React layer is just a hook bridge. As a consequence, a Zustand store can be used outside React — in a Node service, worker, or event bus. This is a complete topic in episode 17.
Context is suitable for values that rarely change, like theme or locale. For state that changes frequently and is read by many components, Context triggers unnecessary re-renders. Zustand wins here because it's selective.
Redux Toolkit answers the problems of old Redux boilerplate and remains a strong choice for large-scale applications, auditing, and teams familiar with the reducer pattern. Zustand wins on simplicity and speed of getting started; both can coexist in a single application.
Jotai (atomic) and Valtio (proxy) are fellow modern libraries from the pmndrs ecosystem. Jotai arranges state into small atoms, while Valtio uses mutations via proxy. Each has its own trade-offs — a deep comparison will be settled in episode 22.
Episode 1 closes the "why" question: Zustand was born from frustration with Redux boilerplate and the weaknesses of Context, designed by the pmndrs team since 2019, and grew into stable v5. The problems it solves: an unnecessary Provider, selective re-renders, small size, and a core independent of React.
Key takeaways:
In the next episode we will break down the core concepts and key architecture of Zustand — the single-store model that holds state and actions, the subscribe/notify mechanism behind the scenes, and the three core APIs useStore, setState, and subscribe. From history, it's now time to get into the engine.