Zustand Source Code Exploration
Dive into the inner workings of Zustand, a minimalist state management library for React. Discover how it leverages the classic Observer Pattern to eliminate unnecessary re-renders, and explore how its binding layer seamlessly connects a framework-agnostic core to React's fiber render pipeline.
Ching HuiMost React developers have experienced this situation. You put shared state into Context. Everything works. Until one update suddenly causes half of your component tree to re-render.
While diving into how Context and useReducer can be optimized to prevent unnecessary re-renders, I was reminded of Zustand—a lightweight state management library in the same realm as Redux and Jotai.

Instead of subscribing to an entire context, every component subscribes only to the state slice it actually needs. That design decision completely changes the rendering behavior.
- Components can subscribe to a specific slice of the state, eliminating the notorious unnecessary re-render issues inherent in the React Context API.
- Furthermore, Zustand's store design is entirely framework-agnostic; it doesn't inherently depend on React or any other framework.
It is elegantly simple yet powerful enough to manage shared state across numerous components. But how does it actually work?
How to use Zustand in React?
import { create } from 'zustand'
const useCountStore = create((set) => ({
count: 0,
incr: () => set((state) => ({ count: state.count + 1 })),
reset: () => set({ count: 0 }),
}))The useCountStore constant holds the hook returned by the create function.
In a React component:
function Counter() {
const count = useCountStore((state) => state.count)
const incr = useCountStore((state) => state.incr)
return <button onClick={incr}>count is {count}</button>
}
function ResetButton() {
const reset = useCountStore((state) => state.reset)
return <button onClick={reset}>reset</button>
}- Notice that there is no
Provider. BothCounterandResetButtonaccess the exact same state without being wrapped in a Context Provider. - Selectors determine the re-render scope. The
Countercomponent only subscribes tocount, whileResetButtononly subscribes to theresetaction, preventing unnecessary updates. - Actions live right alongside the state,
incr,resetand state live together. We don't need to write the dispatch or reducer.
Zustand's source code
vanilla.ts—— The core store itself, which is completely unaware of React's existence.react.ts—— A binding layer that connects the vanilla store to React.
vanilla.ts: The Core Store
At its core, Zustand relies on a classic Observer Pattern.
There is an "observable entity" holding the state. External listeners can "subscribe" to it, and whenever the state updates, the entity "notifies" all subscribers.
More detail about Observer Pattern.
Before looking at Zustand's implementation, let's temporarily forget React. Imagine we want to build the smallest possible state container ourselves.
We only need three things:
- somewhere to store state
- a way to subscribe
- a way to notify everyone after updates
That's exactly the Observer Pattern. A simplified implementation looks like this:
function createObservable(initial) {
let state = initial
const listeners = new Set()
return {
getState: () => state,
setState: (next) => {
state = next
listeners.forEach((listener) => listener(state)) // notify all listeners
},
subscribe: (listener) => {
listeners.add(listener)
return () => listeners.delete(listener) // return unsubscribe
},
}
}Zustand's createStoreImpl is essentially built upon this exact skeleton, with just a few more robust details added.
So .. What is inside of createStoreImpl?
const createStoreImpl = (createState) => {
let state
const listeners = new Set()
const setState = (partial, replace) => {
const nextState =
typeof partial === 'function' ? partial(state) : partial
if (!Object.is(nextState, state)) { // ① bail-out
const previousState = state
state =
(replace ?? (typeof nextState !== 'object' || nextState === null))
? nextState
: Object.assign({}, state, nextState) // ② shallow merge (default)
// ③ Notify
listeners.forEach((listener) => listener(state, previousState))
}
}
const getState = () => state
const getInitialState = () => initialState
const subscribe = (listener) => {
listeners.add(listener)
return () => listeners.delete(listener)
}
const api = { setState, getState, getInitialState, subscribe }
const initialState = (state = createState(setState, getState, api))
return api
}
export const createStore = (createState) =>
createState ? createStoreImpl(createState) : createStoreImplThe entire store is encapsulated within a single closure.
Both state and listeners are private variables enclosed inside this scope. If external code wants to interact with them, the only way is through the exposed methods in the returned api object.
At first glance, setState looks like a normal setter. But it actually performs three independent responsibilities.
- Determine whether anything actually changed.
- Bail-out via Object.is: If the newly computed nextState shares the exact same reference as the current state, the entire block is skipped, and listeners are not notified at all.
- Produce the next state.
- Top-level Shallow Merge by Default: By default, Zustand performs a shallow merge. It uses
Object.assignto merge your provided partial state into the oldstate, preserving all other untouched keys. Note that nested objects are not deeply merged. - If you intend to completely replace the entire state object instead of merging, you can pass `true` as the second argument:
setState(nextState, true).
- Notify every subscriber: Only after passing the first two stages (the reference has changed and the merge is complete) will it trigger
listeners.forEach(...), passing both the new and previous states (state, previousState) to every subscriber.
Even though this is pure Vanilla JS without any framework magic, it is inherently reactive.
import { createStore } from 'zustand/vanilla'
const store = createStore((set) => ({
count: 0,
incr: () => set((s) => ({ count: s.count + 1 })),
}))
// subscribe to a listener
const unsub = store.subscribe((state, prev) => {
console.log(`count: ${prev.count} -> ${state.count}`)
})
store.getState().incr() // log: count: 0 -> 1
store.getState().incr() // log: count: 1 -> 2
unsub() // unscribe
store.getState().incr() // no more logLet's dive into react.ts and connect this core skeleton to React!
setState()
│
▼
vanilla store
│
notify listeners
│
▼
useSyncExternalStore
│
getSnapshot()
│
selector(state)
│
Object.is()
┌──────────┐
│ │
same different
│ │
skip re-render
const createImpl = (createState) => {
const api = createStore(createState) // ← store from vanilla.js
const useBoundStore = (selector) => useStore(api, selector)
Object.assign(useBoundStore, api)
return useBoundStore
}
export const create = (createState) =>
createState ? createImpl(createState) : createImpl- The
createfunction returns a hook that wraps a vanilla store initialized viacreateStore(createState)from 'vanilla.ts'. Object.assign(useBoundStore, api): This meansgetState,setState,subscribe, andgetInitialStateare all attached directly onto the returned hook itself. This brilliant API design explains whyuseCountStorecan act as both a React hook inside components and a standalone object outside of them. You can seamlessly calluseCountStore.getState()oruseCountStore.setState()anywhere in your codebase—even completely outside of the React lifecycle.
// Inside a component
const count = useCountStore((state) => state.count)
// Outside of React (e.g., in an API interceptor or a utility file)
const currentCount = useCountStore.getState().countThe useStore Implementation
export function useStore(api, selector = identity) {
const slice = React.useSyncExternalStore(
api.subscribe,
// getSnapshot
React.useCallback(() => selector(api.getState()), [api, selector]),
// getServerSnapshot
React.useCallback(() => selector(api.getInitialState()), [api, selector]),
)
React.useDebugValue(slice)
return slice
}api.subscribetells React how to listen for changes in the external store.selector(api.getState())tells React what the current state slice looks like.
Whenever the store notifies React that an update has occurred, React invokes getSnapshot again to fetch the latest slice. It then evaluates whether the component needs a re-render based on that slice.
useSyncExternalStore
useSyncExternalStore is a React Hook that lets you subscribe to an external store.

subscribe: Registers a callback function. Whenever the store's state changes, this callback is fired, signaling to React that it's time to check for updates.getSnapshot: Returns the current value extracted from the store. React calls this to grab the slice and usesObject.isbehind the scenes to compare it with the previous snapshot. If they match, React bails out of the re-render.getServerSnapshot: Tailored for Server-Side Rendering. This provides a consistent initial state during server-side rendering and client-side hydration, preventing the notorious "hydration mismatch" error. In Zustand, this maps directly toapi.getInitialState().
From React's perspective, an external store only needs to answer two questions.
- Tell me when something changes. → That's
subscribe. - Tell me what the current snapshot looks like. → That's
getSnapshot.
Whenever a notification arrives, React simply asks for a new snapshot and compares it with the previous one using Object.is. If the snapshot hasn't changed, React skips the render.
That means Zustand isn't deciding whether your component re-renders.
React is.
Zustand merely provides the data.
useSyncExternalStoresource code:function mountSyncExternalStorein https://github.com/react/react/blob/e92ecef2806692f34e9d535da77405eb28464625/packages/react-reconciler/src/ReactFiberHooks.js#L1635
Takeaways
vanilla.ts: Implements a pure Observer Pattern using a simple closure (stateand alistenersSet). ItssetStatemethod perfectly orchestrates the bail-out logic, top-level shallow merging, and subscriber notifications. This core store remains entirely framework-agnostic and completely decoupled from React.react.ts: Acts as a razor-thin binding layer. Thecreatefunction elegantly wraps the vanilla store into a custom React hook while attaching the store APIs directly to it. Meanwhile,useStoreleveragesuseSyncExternalStoreto seamlessly plug this external state right into React's fiber render pipeline.
The true brilliance of Zustand lies in its radical minimalism. It strips down the core logic of "how state is managed and notified" to its absolute bare essentials, while elegantly handing over the responsibility of "how React safely subscribes and schedules re-renders" to React's own native primitives.
