NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #1246 most downloaded on npm
🐻 Bear necessities for state management in React
Last release 1 months ago
13 Aug 2026
Ships fairly regularly
a new release about every 6 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
7 years old
158 releases · first in 2019
This release is mainly for TypeScript users.
This release is mainly for TypeScript users.
State type is stricter.In v3.0.3: <img width="432" alt="image" src="https://user-images.githubusercontent.com/490574/92113834-e1a5d480-ee2a-11ea-88d4-bf0b7cffca2c.png">
In v3.1.0: <img width="434" alt="image" src="https://user-images.githubusercontent.com/490574/92113910-ff733980-ee2a-11ea-944e-230e87d5a035.png">
To fix it: <img width="430" alt="image" src="https://user-images.githubusercontent.com/490574/92114071-39dcd680-ee2b-11ea-9099-3dbe7f63249c.png">
See also:
combine middlewareThis will combine two parts of state into one. The first part is primitive state, and the second part is actions that depend on set.
<img width="431" alt="image" src="https://user-images.githubusercontent.com/490574/92116410-c341d800-ee2e-11ea-9ac1-39deaa4bf745.png">
The resulting type is inferred from the state creator.
<img width="436" alt="image" src="https://user-images.githubusercontent.com/490574/92116514-e4a2c400-ee2e-11ea-8aec-d431ce2cf571.png">
Nothing published for this version
One column per quarter.
This fixes a bug in devtools middleware.
This fixes a bug in devtools middleware.
BREAKING CHANGE in devtools: set now requires replace introduced in v3 api. ref: https://github.com/pmndrs/zustand/issues/159#issuecomment-708417147
This fixes some issues in middleware.
BREAKING CHANGE in devtools: set now requires replace introduced in v3 api. ref: https://github.com/pmndrs/zustand/issues/159#issuecomment-708417147
Nothing published for this version
First of all, this release is 100% backward compatible, it will not break your code! The only breaking change (the create functions return value) stil…
First of all, this release is 100% backward compatible, it will not break your code! The only breaking change (the create functions return value) still can work in the old way, but throws a small deprecation warning.
Our main focus has been:
We will soon publish an experimental V4 that utilizes react-experimentals useMutableSource in concurrent mode. The groundwork for this has been laid in this major.
import create from 'zustand'
const useStore = create(set => ({
bears: 0,
increasePopulation: () => set(state => ({ count: state.bears + 1 })),
resetPopulation: () => set({ bears: 0 })
}))
function BearCounter() {
const bears = useStore(state => state.bears)
return <h1>{bears} around here ...</h1>
}
function Controls() {
const increasePopulation = useStore(state => state.increasePopulation)
return <button onClick={increasePopulation}>one up</button>
}
Sometimes you need to access the state in a non-reactive way, or act upon the store. For these cases the resulting hook has utility functions attached to its prototype.
const useStore = create(() => ({ paw: true, snout: true, fur: true }))
// Getting non-reactive fresh state
const paw = useStore.getState().paw
// Listening to all changes, fires on every change
const unsub1 = useStore.subscribe(console.log)
// Listening to selected changes, in this case when "paw" changes
const unsub2 = useStore.subscribe(console.log, state => state.paw)
// Updating state, will trigger listeners
useStore.setState({ paw: false })
// Unsubscribe listeners
unsub1()
unsub2()
// Destroying the store (removing all listeners)
useStore.destroy()
// You can of course use the hook as you always would
function Component() {
const paw = useStore(state => state.paw)
Zustands core can be imported and used without the React dependency. The only difference is that the create function does not return a hook, but the api utilities.
import create from 'zustand/vanilla'
const store = create(() => ({ ... }))
const { getState, setState, subscribe, destroy } = store
You can even consume an existing vanilla store with React:
import create from 'zustand'
import vanillaStore from './vanillaStore'
const useStore = create(vanillaStore)
The set function has a second argument, false by default. Instead of merging, it will replace the state model. Be careful not to wipe out parts you rely on, like actions.
import omit from "lodash-es/omit"
const useStore = create(set => ({
salmon: 1,
tuna: 2,
deleteEverything: () => set({ }), true), // clears the entire store, actions included
deleteTuna: () => set(state => omit(state, ['tuna']), true)
}))
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Removed SubscribeOptions and UseStoreSubscribeOptions types.
Removed ESM and IIFE versions of middleware.js and shallow.js. Any imports of the ".cjs" files should be changed from "zustand/{name}.cjs" to just "zu
api.subscribe has a new function signature that removes the object wrapper: api.subscribe(listener, selector?, equalityFn?).StateListener type has changed. An overloaded signature was added for better error handling.Subscribe type has changed. It uses the updated StateListener type.listeners are iterated in a different order than they were before. Parent to child rather than child to parent. It would be rare if this causes any issues.useStore was removed. useStore will throw an Uncaught TypeError if the second arg is an array.Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →