Registry / web-framework / zustand-mutative

zustand-mutative

JSON →
library1.3.1jsnpmunverified

zustand-mutative is a middleware for Zustand that integrates the Mutative library, enabling efficient and convenient immutable state updates using a mutable syntax. It allows developers to modify Zustand state directly, similar to libraries like Immer, but claims significantly higher performance (2-6x faster than spread operations, over 10x faster than `zustand/middleware/immer`). The current stable version is 1.3.1. Releases appear to be driven by dependency updates and minor fixes, with new versions roughly every few months, often coinciding with updates to `mutative` or `zustand` itself. Its key differentiator is its performance advantage over other immutable update helpers within the Zustand ecosystem while providing a familiar mutable-style API for state management.

npm install zustand-mutative
INSTALL
IMPORT
SIG · ZUSTAND-MUTATIVE
Z
zustand-mutative
web-frameworkjavascriptv1.3.1
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

mutative
import { mutative } from 'zustand-mutative';
const mutative = require('zustand-mutative').mutative;
Primarily designed for ESM and TypeScript usage. While CommonJS `require` might work with transpilation, direct ESM import is idiomatic and recommended.
create
import { create } from 'zustand';
import create from 'zustand';
`create` is a named export from `zustand`, not a default export.
StoreDefinition
create<State & Actions>()(mutative((set) => ({ ... })));
create(mutative((set) => ({ ... })));
Using TypeScript generics `<State & Actions>` is crucial for type safety when defining your store with `zustand-mutative`.

This quickstart demonstrates how to define a Zustand store using `zustand-mutative` middleware, enabling direct, mutable-style updates to an immutable state object, including primitive values and array/object mutations.

import { create } from 'zustand'; import { mutative } from 'zustand-mutative'; type State = { count: number; items: { id: string; value: number }[]; }; type Actions = { increment: (qty: number) => void; decrement: (qty: number) => void; addItem: (id: string, value: number) => void; updateItem: (id: string, newValue: number) => void; }; export const useCountStore = create<State & Actions>()( mutative((set) => ({ count: 0, items: [], increment: (qty: number) => set((state) => { state.count += qty; }), decrement: (qty: number) => set((state) => { state.count -= qty; }), addItem: (id: string, value: number) => set((state) => { state.items.push({ id, value }); }), updateItem: (id: string, newValue: number) => set((state) => { const item = state.items.find((item) => item.id === id); if (item) { item.value = newValue; } }), })) ); // Example usage (not part of the store definition, but runnable) // const store = useCountStore.getState(); // store.increment(5); // store.addItem('a', 10); // store.updateItem('a', 20); // console.log(useCountStore.getState().count); // Expected: 5 // console.log(useCountStore.getState().items); // Expected: [{ id: 'a', value: 20 }]
Debug
Known issues
breakingVersion 1.1.0 upgraded its peer dependencies, specifically `zustand` to `v5` and `mutative` to `v1.1.0`. Users on older major versions of these dependencies will need to upgrade them to match, which may introduce breaking changes from those libraries themselves.
fix
Ensure your project's `zustand` and `mutative` versions meet the peer dependency requirements specified in `zustand-mutative`'s `package.json` (e.g., `zustand: ^4.0 || ^5.0`, `mutative: ^1.3.0`).
affects: >=1.1.0
gotchaWhen performing updates within the `set` function, always modify the `state` object directly. Returning a new object from `set` when using `mutative` middleware will bypass its capabilities and potentially lead to unexpected behavior or performance degradation.
fix
Within the `set` callback provided to `mutative`, ensure all state changes are done by directly mutating the `state` parameter, e.g., `state.count += 1;`.
affects: >=1.0.0
gotchaThe `mutative` middleware is designed for scenarios where you need to perform complex nested updates efficiently. For very simple, shallow updates, directly using Zustand's `set` with spread syntax (`set((state) => ({ ...state, key: newValue }))`) might be sufficient and avoid the overhead of a middleware.
fix
Evaluate the complexity of your state updates. For simple, shallow changes, direct `set` with spread syntax is an option. For nested, complex, or performance-critical immutable updates, `zustand-mutative` is recommended.
affects: >=1.0.0
breakingVersion 1.2.0 added support for React v19 as a peer dependency. While this is generally an improvement, projects specifically locking to older React versions should be aware of potential dependency resolution conflicts if their package manager strictly enforces peer dependencies.
fix
If encountering peer dependency issues with React, ensure your React version is within the supported range (`^17.0 || ^18.0 || ^19.0`). Consider using `legacy-peer-deps` or similar options with your package manager temporarily if you are unable to upgrade React immediately.
affects: >=1.2.0
Errors
Common errors & fixes
Error: 'mutative' does not contain an export named 'mutative'.
Attempting to import `mutative` from the `mutative` package instead of `zustand-mutative`.
fix
Ensure you are importing the `mutative` middleware from `zustand-mutative` like so: `import { mutative } from 'zustand-mutative';`.
TypeError: Cannot assign to read only property 'foo' of object '#<Object>'
This error can occur if `zustand-mutative` is not correctly applied or if `mutative`'s auto-freeze option is enabled in development, and you are trying to mutate a frozen object outside the `set` callback, or if strict mode issues are present.
fix
Ensure the `mutative` middleware is correctly wrapped around your store definition. If you've enabled `autoFreeze` in Mutative options, all mutations must occur within the `set` callback provided by `zustand-mutative`. Check Mutative's strict mode documentation for more advanced debugging.
TS2307: Cannot find module 'zustand-mutative' or its corresponding type declarations.
TypeScript cannot find the module or its types. This often happens due to incorrect module resolution settings (e.g., `moduleResolution: 'NodeNext'` without proper `package.json` exports mapping) or outdated package installations.
fix
Ensure `zustand-mutative` is correctly installed. For `NodeNext` resolution issues, verify your `tsconfig.json` and `package.json` (`exports` field) are configured correctly, or update to `zustand-mutative@^1.2.1` or later which includes fixes for these types of import issues.
Upgrade
Version history
1.3.1latest on npm
Audit
Dependencies
mutativerequiredCore dependency for mutable-style immutable state updates.
zustandrequiredThe state management library this middleware extends.
reactoptionalPeer dependency for Zustand stores used in React environments.
@types/reactoptionalTypeScript type definitions for React, required for type checking in React environments.
Agent activity
66 hits · last 30 days
node
56
OpenAI (training)
1
Resources