Registry / web-framework / zustand-computed

zustand-computed

JSON →
library2.1.2jsnpmunverified

Zustand-computed is a lightweight, TypeScript-friendly middleware designed for the Zustand state management library, enabling the creation of derived or 'computed' state based on the existing store state. The current stable version is 2.1.2, released in April 2026. The package maintains an active release cadence, with multiple bug fixes and minor features released within the last year, demonstrating ongoing development and support. Its primary differentiator is its simplicity and direct integration with Zustand's middleware pattern, providing a straightforward way to add calculated properties to a store without manual memoization or complex selectors. It focuses on functional transformations and offers options to optimize recomputation with `keys` or a `shouldRecompute` function, differentiating it from purely selector-based approaches by integrating computed values directly into the store's state tree.

npm install zustand-computed
INSTALL
IMPORT
SIG · ZUSTAND-COMPUTED
Z
zustand-computed
web-frameworkjavascriptv2.1.2
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.

createComputed
import { createComputed } from 'zustand-computed'
import computed from 'zustand-computed' // Breaking change in v2.0.0
The `computed` middleware was replaced by `createComputed` function in v2.0.0. Ensure you use named import.
create
import { create } from 'zustand'
import create from 'zustand'
While not directly from `zustand-computed`, `create` from `zustand` is essential. In newer Zustand versions, `create` is typically a named export.
ComputedStore
type ComputedStore = { countSq: number }
When using TypeScript, it's recommended to define a specific type for your computed state, separate from your base store state, for clear type inference and safety.

This quickstart demonstrates how to define a Zustand store with computed state using `createComputed`, including TypeScript types, and basic state manipulation. It shows how the computed property (`countSq`) becomes part of the store's observable state and is accessible like any other state property.

import { create } from 'zustand' import { createComputed } from 'zustand-computed' type Store = { count: number inc: () => void dec: () => void } type ComputedStore = { countSq: number } const computed = createComputed((state: Store): ComputedStore => ({ countSq: state.count ** 2, })) // To integrate with other middleware like devtools or immer, wrap them around computed // For example: create<Store>()(devtools(computed(...))) or create<Store>()(immer(computed(...))) const useStore = create<Store>()( computed( (set, get) => ({ count: 1, inc: () => set((state) => ({ count: state.count + 1 })), dec: () => set((state) => ({ count: state.count - 1 })), // get() function inside the store definition has access to both base and computed state square: () => set(() => ({ count: get().countSq })), root: () => set((state) => ({ count: Math.floor(Math.sqrt(state.count)) })), }) ) ) // Example usage (e.g., in a React component) function Counter() { const { count, countSq, inc, dec } = useStore() return ( <div> <span>Count: {count}</span> <br /> <span>Count Squared: {countSq}</span> <br /> <button onClick={inc}>+1</button> <button onClick={dec}>-1</button> </div> ) } // To demonstrate outside React, for example in Node.js: const unsubscribe = useStore.subscribe((state) => { console.log('Current state:', state.count, 'Computed:', state.countSq); }); useStore.getState().inc(); // Increment count, triggering recomputation useStore.getState().inc(); unsubscribe();
Debug
Known issues
breakingThe `computed` middleware was replaced by `createComputed` function. This requires changing your import and how you apply the middleware.
fix
Change `import computed from 'zustand-computed'` to `import { createComputed } from 'zustand-computed'`. Update usage from `create(computed(...))` to `create(createComputed(...)(...))`.
affects: >=2.0.0
gotchaEarlier versions used a Proxy for computed state, which could lead to unexpected behavior or performance issues in some scenarios. This was removed in v2.1.0.
fix
No direct fix needed if upgrading to v2.1.0 or later, as the problematic Proxy behavior has been removed. Ensure your logic doesn't rely on Proxy-specific behaviors.
affects: >=2.1.0
gotchaWhen combining `zustand-computed` with other Zustand middleware like `immer`, compatibility issues (e.g., throwing errors) have been reported and fixed in recent versions.
fix
Ensure you are on `zustand-computed` v2.1.2 or newer, which includes specific fixes for Immer compatibility. Review middleware order, typically `immer(computed(...))` or `devtools(immer(computed(...)))`.
affects: >=2.1.1
gotchaThe internal import path for `zustand` changed from `zustand` to `zustand/vanilla` in a previous version, which could affect bundling or specific environments.
fix
No direct user fix is needed for this internal change. However, if you experience bundling issues with older `zustand-computed` versions, ensure you're on a recent version. This was an internal fix.
affects: >=1.4.1
gotchaBy default, the compute function runs on every store change. For complex computations, this can be inefficient. Optimization options are available.
fix
Pass an options object to `createComputed` with `keys` (an array of state keys to watch) or `shouldRecompute` (a function comparing previous and next state) to control when recomputation occurs.
affects: >=1.0.0
Errors
Common errors & fixes
TypeError: store.use is not a function
`computed` was used as a middleware directly, instead of being called as a function, or the wrong import for `create` was used.
fix
Ensure `createComputed` is imported correctly and called as a function (e.g., `create(createComputed(...)(...))`). Also, confirm `create` is imported from 'zustand' as `import { create } from 'zustand'`.
Property 'computedValue' does not exist on type 'StoreType'.
TypeScript compiler error indicating that the computed properties are not correctly merged into the store's type definition.
fix
Ensure your `create` call is correctly typed to include both your base `Store` type and the `ComputedStore` type. For example: `create<Store, [['chrisvander/zustand-computed', ComputedStore]]>(computed(...))`.
Error: An Immer producer returned a new value without a change.
Using `zustand-computed` with `immer` middleware where computed state changes are incorrectly handled or trigger unexpected Immer behavior.
fix
Update to `zustand-computed` v2.1.2 or newer to leverage bug fixes specifically for Immer compatibility. Ensure the order of middleware is correct, typically `immer(computed(...))`.
Upgrade
Version history
2.1.2latest on npm
Audit
Dependencies
reactrequiredPeer dependency for Zustand stores typically used in React applications.
zustandrequiredCore state management library that this middleware extends.
Agent activity
40 hits · last 30 days
node
32
OpenAI (training)
1
Resources
zustand-computed — npm install zustand-computed · libregistry