zustand
5.0.16 · 22 Oct 2026MIT87.8M / weekRepositorynpmAtom feed
124 stable releases, newest first, by release line. Notes are quoted as the maintainers published them.
- 4.x
4.0.0
26 Jul 2022- breaking
vanilla: Drop deprecated store.subscribe with selector
- breaking
middleware: Drop deprecated persist options and make removeItem required
- breaking
core: Drop v2 hook compatibility
Zustand v4 is here
Backward compatible with v3 in JS
v4 API is completely backward compatible, so it's just nothing to update if you are JS users.
One note is v4 depends on use-sync-external-store.
There might be some bundling issues.
Please report them if you encounter such cases.TypeScript types are rewritten
To better support types with middleware, v4 TypeScript code is rewritten.
Please find docs/typescript.md for more information.New API for context usage
In v3,
zustand/contextis provided as a workaround.
v4 API exposescreateStoreanduseStore, which are more flexible.
Please read this for usage.
If you are unsure about the usage, open a new discussion.Counter example: codesandbox.io/s/polished-pond-4jn1e2
Deprecated APIs are removed
Some APIs are already deprecated in v3, and they are removed in v4. Please make sure to update to the latest version of v3 before migrating to v4.
What's Changed
- breaking
vanilla: Drop deprecated store.subscribe with selector
- breaking
middleware: Drop deprecated persist options and make removeItem required
- breaking
core: Drop v2 hook compatibility
- breaking
types: Drop deprecated UseStore type
use-sync-external-store
- breaking
middleware/devtools: Use official devtools extension types
- breaking
middleware/devtools: Remove deprecations and warnings
build: Separate vanilla build
- breaking
types: Add higher kinded mutator types
index: Export createStore from vanilla
middleware: Separate immer middleware
middleware/devtools: Add
enabledoption and show devtools warning only if enabled- breaking
middleware/devtools: Remove checking old string option
Fix TS4023 and other minor changes
types: Avoid any in react.ts
build: Add downlevel-dts
types: Mark more methods bivariant
shallow: Restrict types
persist: Add method getOptions on persist api and update documentation
types: Minimize types by deprecating them
build: A workaround for ESM for use-sync-external-store
types: Use TS interfaces only for public api
shallow: Types with useStore
shallow: Types with useStore again
- 3.x
3.7.2
7 Apr 2022middleware/persist: Merge storage value with the latest store state
This fixes an issue in
persistfor some use cases.What's Changed
middleware/persist: Merge storage value with the latest store state
3.7.1
28 Feb 2022- deprecated
middleware/devtools: Deprecate serialize.options
context: Revert removing overloads in
UseContextStore
This fixes a type issue with
zustand/contextin v3.7.0.What's Changed
context: Revert removing overloads in
UseContextStore- deprecated
middleware/devtools: Deprecate serialize.options
3.7.0
10 Feb 2022devtools: Don't show jsdoc deprecation warning when no options are passed
middleware: Match vanilla StateCreator type in subscribeWithSelector
build: Use
__DEV__to control development mode
This release is to prepare for v4 release, which will include some breaking changes. Especially typing store with middleware will be changed. This release gives partial migration path (see
tests/middlewareTypes.test.tsxfor examples), so it's highly recommended to try this version before v4 comes and report issues.It also fixes some small typing issues and improves UMD/SystemJS bundling. Oh, and last but not least, vite users don't need to set
NODE_ENVanymore.What's Changed
devtools: Don't show jsdoc deprecation warning when no options are passed
middleware: Match vanilla StateCreator type in subscribeWithSelector
build: Use
__DEV__to control development modeMigrations regarding higher kinded mutators for v4
3.6.9
10 Jan 2022build: Generate umd and system files
This adds UMD and SystemJS builds for CDN.
What's Changed
build: Generate umd and system files
3.6.8
24 Dec 2021- deprecated
middleware/devtools: Deprecate passing name directly instead of an object
middleware/devtools: Minor fixes for pause recording feature
middleware/devtools: Revert extension connector with try-catch to fix RN usage
This fixes some issues in
devtoolsmiddleware.What's Changed
middleware/devtools: Minor fixes for pause recording feature
middleware/devtools: Revert extension connector with try-catch to fix RN usage
- deprecated
middleware/devtools: Deprecate passing name directly instead of an object
3.6.7
7 Dec 2021middleware: Devtools work in non-browser
There was a regression in
devtoolsmiddleware in v3.6.6, which is fixed.What's Changed
middleware: Devtools work in non-browser
3.6.6
3 Dec 2021Rewrite
devtools
This fixes and improves
devtoolsmiddleware. The basic usage shouldn't be changed. If you have questions on usage, please open a new discussion.What's Changed
Rewrite
devtools
3.6.5
9 Nov 2021types: Fix core types to better handle middleware types
middleware: Add onFinishHydration to persist api
This version further improves to fix some typing issues introduced in v3.6.0 and fixes persist api introduced in v3.6.3.
What's Changed
types: Fix core types to better handle middleware types
middleware: Add onFinishHydration to persist api
3.6.4
3 Nov 2021middleware: Devtools to patch api.setState with namedSet and fix middleware types
This improves devtools middleware and typing of other middlewares. Please feel free to update and report any issues.
What's Changed
middleware: Devtools to patch api.setState with namedSet and fix middleware types
3.6.3
2 Nov 2021core: useDebugValue in useStore
middleware: Add persist api
The new persist middleware exposes persist api in store. This is thanks to the new customizable store api types introduced in v3.6.
What's Changed
core: useDebugValue in useStore
middleware: Add persist api
3.6.2
30 Oct 2021middleware: Simplify middleware types and allow explicit typing
v3.6.0 introduced middleware types trying to infer store types as much as possible. However, it doesn't work well for several cases, and users need to type manually which was actually hard. In this version, middleware types are simplified and let users to explicitly type when needed more easily. Many examples are in
tests/middlewareTypes.test.tsx. If you find issues or need some more typing examples, please report them.What's Changed
middleware: Simplify middleware types and allow explicit typing
3.6.1
26 Oct 2021context: Custom store type for createContext
middleware: Devtools dispatch support
middleware: Types and devtools
Summary
This fixes some type issues introduced in v3.6.0.
devtoolsis improved to accept updating state from DevTools Ext.What's Changed
context: Custom store type for createContext
middleware: Devtools dispatch support
middleware: Types and devtools
3.6.0
21 Oct 2021types: Better middleware support
types: Rename from UseStore to UseBoundStore
middleware: subscribeWithSelector middleware
Summary
This version mainly comes with type improvement for middleware. It's tricky implementation-wise. Please report issues and let's look for solutions or workarounds.
It has renamed and deprecated types:UseStore👉UseBoundStore
A newsubscribeWithSelectormiddleware is added, deprecating the equivalent feature in core.Migrating to
subscribeWithSelectormiddlewarePreviously, you could do this:
const useStore = create(...) useStore.subscribe(callback, selector, equalityFn)
which is deprecated and replaced with:
const useStore = create(subscribeWithSelector(...)) useStore.subscribe(selector, callback, { equalityFn }) // selector is not optionalWhat's Changed
types: Better middleware support
types: Rename from UseStore to UseBoundStore
middleware: subscribeWithSelector middleware
3.5.14
19 Oct 2021middleware: Export PersistOptions type definitions
middleware: Jump state support in devtools
Summary
Fixed a regression in
devtoolsthat was introduced in v3.5.11.What's Changed
middleware: Export PersistOptions type definitions
middleware: Jump state support in devtools
3.5.13
7 Oct 2021persist: Add partialize option
The
persistmiddleware has a new optionpartializewhich works for nested properties, deprecatingblacklistandwhitelistoptions.persist: Add partialize option
3.5.12
1 Oct 2021package: Avoid subpath pattern in exports
v3.5.11 accidentally requires newer node.js versions. v3.5.12 fixes it by reverting exports format.
package: Avoid subpath pattern in exports
3.5.11
28 Sep 2021Remove useless internal info in devtools
⚠️ Minimum Node.js requirements (for server-side usage like Next.js): v14.13.0, v12.20.0
This improved
devtoolsmiddleware. There can still be room for improvement. Free free to open issues and feature requests, and possibly contribute to them.Remove useless internal info in devtools
3.5.10
26 Aug 2021Allow optional REDUX DEVTOOLS "options" object
Rollback to initial exports structures with duplicated .js and .mjs files for additional support of bundlers
Our fixes for ESM in v3.5.8 and v3.5.9 were somewhat good and somewhat bad. Now, this should be the better one based on our experience and reported issues. If you still have some issues, please file them.
Allow optional REDUX DEVTOOLS "options" object
Rollback to initial exports structures with duplicated .js and .mjs files for additional support of bundlers
3.5.9
17 Aug 2021Package all files into a single dist folder
We've been struggling with providing package that works for various bundlers and node.
v3.5.8 was expected to solve the issue with node, but it turned out having an issue with webpack 5.
We basically gave up supporting old bundlers. v3.5.9 comes with simplified builds with latest standard.Note for old bundlers like webpack 4: Unlike previous versions, the bundler will pick cjs build by default. If you need module build, it should be explicit. Free free to open an issue for questions and discussions.
Package all files into a single dist folder
3.5.8
13 Aug 2021build: Improved ESM support for most used bundlers with fallbacks for older bundlers
This improves ESM build.
build: Improved ESM support for most used bundlers with fallbacks for older bundlers
3.5.7
13 Jul 2021context: Export UseContextStore interface
This includes a fix for
zustand/contextfor TypeScript.context: Export UseContextStore interface
3.5.6
9 Jul 2021Revert Provider initialStore types
Improve createContext's useStore types
Package.json exports to have import
This fixed
zustand/contexttypes and added "import" export entries for modern bundlers.Revert Provider initialStore types
Improve createContext's useStore types
Package.json exports to have import
3.5.5
29 Jun 2021persist: onRehydrateStorage argument not containing the final state
persist: Add a merge function option
Do not use generator to support IE11
This supports IE11 again. (v3.5.3 and v3.5.4 have an issue.)
It also has various fixes and improvements in the persist middleware.persist: onRehydrateStorage argument not containing the final state
persist: Add a merge function option
Do not use generator to support IE11
persist: Incorrect deserialize return type
persist: Not hydrating when the stored item doesn't contain a version
3.5.4
22 Jun 2021Cjs build, no regenerator
v3.5.3 has an issue in CJS build. Please use this instead.
Cjs build, no regenerator
3.5.3
22 Jun 2021Export NamedSet type for combining with immer
middleware/persist: Argument of onRehydrateStorage for missing migrate function
Make type NamedSet compatible with type SetState
(v3.5.3 includes #419, which causes a build issue in CJS. Please use v3.5.4)
This includes some type improvements in
zustand/middlewareand improvements/changes inzustand/context.Export NamedSet type for combining with immer
middleware/persist: Argument of onRehydrateStorage for missing migrate function
Make type NamedSet compatible with type SetState
context: Stable storeApi
Fix/context create store
3.5.2
5 Jun 20213.4.0
6 Apr 2021- breaking
Index.cjs.js is renamed to index.js (explicit cjs usage is no longer documented in readme)
- breaking
Index.iife.js is removed (never documented and not configured properly)
(IMPORTANT: It turns out that this version has a serious issue in CJS build. Please use v3.4.1 instead.)
This release is mainly to change build tooling and package file structure. It now uses esbuild to build esm bundles. The esm bundles are in
esmfolder, and default cjs bundles are in the root folder.- breaking
Index.cjs.js is renamed to index.js (explicit cjs usage is no longer documented in readme)
- breaking
Index.iife.js is removed (never documented and not configured properly)
Changes:
3.3.0
8 Jan 2021- breaking
storageoptions is replaced withgetStorage - breaking
New
blacklist/whitelistoptions - breaking
New
onRehydrateStorageoption
3.2.0
16 Nov 2020This release improves scoped subscription api (subscription with selector).
[BREAKING CHANGE]
This includes a breaking change in undocumented api and behavior.Pre-v3.2:
const store = create(...) store.subscribe((foo, error) => { ... }, state => state.foo) // errors in the selector are caught and passed as the second argument of the listener.v3.2:
const store = create(...) store.subscribe((foo, prevFoo) => { ... }, state => state.foo) // the second argument of the listener is previous value and errors in the selector are not caught.3.1.0
3 Sep 2020This release is mainly for TypeScript users.
The base
Statetype is stricter.In v3.0.3:
In v3.1.0:
To fix it:
See also:
New
combinemiddlewareThis will combine two parts of state into one. The first part is primitive state, and the second part is actions that depend on
set.The resulting type is inferred from the state creator.
3.0.1
18 Aug 20203.0.0
17 Aug 2020Stability and fixing bugs
Making it suitable for concurrent mode
Supporting React-fast-refresh
What's new
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:
Stability and fixing bugs
Making it suitable for concurrent mode
Supporting React-fast-refresh
Making it more versatile so that it can be used without React
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.
Simpler API !(img.shields.io/badge/-deprecations-red)
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> }Utility functions are on the hooks prototype !(img.shields.io/badge/-deprecations-red)
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)Using zustand without React
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 } = storeYou can even consume an existing vanilla store with React:
import create from 'zustand' import vanillaStore from './vanillaStore' const useStore = create(vanillaStore)
Overwriting state
The
setfunction 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) }))- 2.x