Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

Zustand · Const

mutative middleware

Zustand's immer middleware enables immutable updates using mutable-style draft syntax. It wraps a state creator and lets Immer produce the next state from draft mutations.

How it works

The immer middleware wraps a Zustand state creator so its update functions can modify an Immer draft directly. Immer then creates the immutable next state, avoiding manual copying while preserving Zustand's immutable-state model.

Syntax

immer<T>(stateCreatorFn: StateCreator<T, [], []>): StateCreator<T, [['zustand/immer', never]], []>

Parameters

NameTypeDescription
stateCreatorFnStateCreator<T, [], []>The Zustand state creator to wrap; it receives set, get, and store and normally returns the store's state and actions.

Returns

A state creator function typed with the ['zustand/immer', never] mutator.

Key points

  • Use the middleware when update logic would otherwise require verbose object or array copying.
  • Its typed signature accepts a base state creator and returns one carrying the Zustand Immer mutator.
  • The wrapped creator receives Zustand's set, get, and store arguments just like an ordinary state creator.

Common mistakes

  • Install Immer as a direct dependency before importing and using this middleware.

Example: Update state with mutable syntax

import { create } from 'zustand'
import { immer } from 'zustand/middleware/immer'

type State = {
  count: number
  increment: (qty: number) => void
}

export const useCountStore = create<State>()(
  immer((set) => ({
    count: 0,
    increment: (qty) =>
      set((state) => {
        state.count += qty
      }),
  })),
)

The middleware lets the updater edit a draft directly while Immer produces the immutable next state.

When to use it

Nested object changes

Updating deeply nested state

Collection updates

Changing items inside arrays or keyed collections

Boilerplate reduction

Reducing repetitive spread and copy operations

Interview questions

QHow does Zustand's Immer middleware make mutable-looking updates safe?

immer accepts a Zustand state creator and returns another state creator. Its updater receives a draft, so code such as state.count += qty is allowed while Immer generates the immutable result.

Follow-up: What type-level mutator does it add? It changes the creator type to include ['zustand/immer', never].

QHow do you add the middleware to a store?

The middleware is imported from zustand/middleware/immer, and Immer must be installed separately. It is applied inside create, wrapping the state creator.

Follow-up: Why is the dependency direct rather than transitive? The middleware relies on the Immer package at runtime, so the application must provide it.

QWhat problem does this middleware solve?

Immer is intended to simplify updates to immutable data structures by removing the need to manually copy the entire object. The resulting state still follows Zustand's change-detection behavior.

Follow-up: What can happen with a non-immerable class? The class may be mutated outside a proxy, making current and next state equal and causing subscriptions not to run.

  • create
  • zustand/middleware/immer
  • Immer
  • StateCreator
  • set

Source: immer - Zustand Docs. Checked 2026-10-15.