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

Zustand · Const

immer producer

The immer middleware enables convenient immutable updates in Zustand. Wrap a state creator with it to write draft mutations inside set callbacks.

How it works

The immer middleware adapts a Zustand state creator so updater callbacks receive Immer drafts. This permits direct-looking mutations such as state.count += qty; Immer converts them into immutable updates before Zustand publishes the result.

Syntax

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

Parameters

NameTypeDescription
stateCreatorFnStateCreator<T, [], []>A Zustand state creator receiving set, get, and store, usually returning the state and actions to expose.

Returns

A state creator function: StateCreator<T, [['zustand/immer', never]], []>

Key points

  • It provides immutable state transitions through a more convenient mutable-looking update style.
  • Immer is especially useful when changing values several levels deep in a state object.
  • The wrapped creator receives Zustand's set, get, and store arguments.
  • Its result is another state creator that can be supplied to a Zustand store factory.

Common mistakes

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

Example: Increment nested state with Immer

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

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

const useStore = create<Store>()(
  immer((set) => ({
    count: 0,
    increment: () =>
      set((state) => {
        state.count += 1
      }),
  })),
)

useStore.getState().increment()
console.log(useStore.getState().count)

Wrap the state creator with immer, then mutate the draft inside a set callback while Immer produces the immutable next state.

When to use it

Deeply nested updates

Updating objects or records several levels below the store root.

Concise action implementations

Writing counters and other action logic without manually spreading state layers.

Immutable updates with draft syntax

Keeping Zustand's immutable state model while using mutable-looking draft code.

Interview questions

QWhat does the immer middleware do?

immer takes a Zustand state creator and returns another state creator with Immer-aware updates. The wrapped creator can use set((state) => { state.count += qty }), and Immer turns that draft mutation into an immutable state transition.

Follow-up: What does the middleware return? It returns a state creator function, with the Zustand Immer mutator type applied.

QWhat is the signature and input of immer?

The middleware signature is immer<T>(stateCreatorFn: StateCreator<T, [], []>): StateCreator<T, [['zustand/immer', never]], []>. Its input creator receives set, get, and store, and normally returns the store's exposed state and actions.

Follow-up: Why can an updater mutate state safely? The callback operates on an Immer draft, while the resulting store state remains immutable.

QWhat setup or usage pitfalls does the documentation identify?

Immer must be installed as a direct dependency, and updates must follow Immer's rules. In particular, class objects require [immerable] = true; otherwise Zustand may see unchanged references and skip subscriptions.

Follow-up: What symptom can incorrect class handling cause? The current and next state can compare equal, so subscribers may not be called.

  • set
  • get
  • store
  • StateCreator
  • zustand/middleware/immer
  • Immer

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