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

Zustand · Const

middleware order

Zustand middleware is nested, and devtools should usually be the outermost wrapper. With Immer, use devtools(immer(...)) so DevTools is applied last and other middleware cannot mutate setState first.

How it works

Middleware composition is nested: the outer middleware is applied last around the inner ones. Zustand recommends putting devtools as the outermost wrapper so other middleware cannot mutate setState after DevTools has configured it.

Syntax

devtools(immer((set) => ({ ... })))

Key points

  • Put devtools at the outer edge of the middleware composition whenever possible.
  • With Immer, the preferred nesting is devtools(immer(...)).
  • Applying DevTools last prevents preceding middleware from changing setState before DevTools receives it.
  • TypeScript does not require a separate middleware-specific setup beyond the normal typed store pattern.
  • Place middleware directly inside create so TypeScript can infer the contextual types.

Common mistakes

  • Putting devtools inside another middleware can produce the wrong composition order; wrap the other middleware with devtools instead.
  • For an immer combination, use devtools(immer(...)), not the reverse nesting.

Example: Apply devtools last

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

type BearState = {
  bears: number
  increase: (by: number) => void
}

const useBearStore = create<BearState>()(
  devtools(
    immer((set) => ({
      bears: 0,
      increase: (by) =>
        set((state) => {
          state.bears += by
        }),
    })),
  ),
)

useBearStore.getState().increase(2)
console.log(useBearStore.getState().bears)

Place devtools outside immer so it is applied last in the middleware composition.

When to use it

Combine Immer with DevTools

A store uses Immer for concise immutable updates and Redux DevTools for inspection.

Control a middleware stack

Several middleware functions wrap one store creator and their application order affects behavior.

Preserve TypeScript inference

A TypeScript store needs contextual inference while middleware is composed.

Interview questions

QHow should Zustand middleware be ordered when using DevTools?

Middleware is composed by nesting state creators. The recommended arrangement puts devtools on the outside, making it the last middleware applied and preserving its control over setState.

Follow-up: What ordering should be used with immer? Use devtools(immer(...)), because devtools should be applied last.

QWhat is the correct devtools and immer nesting?

Use devtools(immer(...)), rather than immer(devtools(...)). The outer devtools wrapper ensures the DevTools middleware is applied last.

Follow-up: Why does the order matter? Other middleware may mutate setState; placing DevTools last prevents that mutation from occurring before DevTools observes it.

QWhy does Zustand recommend putting devtools last?

DevTools should be placed at the end of the middleware chain. This means it wraps the other middleware rather than being wrapped by it.

Follow-up: Does combine require special middleware mutator handling? No; the documentation says combine does not mutate the store.

  • devtools
  • immer
  • persist
  • subscribeWithSelector
  • combine
  • create

Source: Middleware that changes the.... Checked 2026-10-15.