Immer: Write Mutable Code for Immutable State

Immer lets you write simple, mutable-style code to produce an immutable next state. It's essential in Redux or with React's useState to avoid complex spread operators for deep updates. The footgun: mutations are only safe inside Immer's produce function.
Why it exists
Updating nested immutable data structures in JavaScript is tedious and error-prone. It requires manually creating copies at every level of the object tree, typically using multiple spread operators (...). This boilerplate is verbose, hard to read, and it's easy to accidentally mutate the original state, leading to subtle bugs.
The mental model
Think of Immer as a personal assistant for your state. You give the assistant your current state (a letter). The assistant gives you back a special draft copy. You can freely scribble changes on this draft using plain JavaScript mutations. When you're done, you hand the draft back, and the assistant produces a clean, final version (the next state) that incorporates your changes, leaving the original letter untouched.
How it works
Immer's core is the produce function: produce(currentState, recipe). The recipe is a function that receives a draft of your state. This draft is a proxy object that you can safely mutate. You can push to arrays, assign to object properties, or delete keys directly on the draft. Immer records all these operations. Once your recipe function completes, Immer efficiently produces the next immutable state by applying your recorded changes, creating new objects only for the parts of the state tree you touched. Unchanged parts are shared with the original state, which is a performance optimization called structural sharing.
When to use it
Use Immer whenever you have complex or nested state that needs to be updated immutably. It is a perfect fit for Redux reducers, React's useReducer hook, or even useState when the state is an object or array. It drastically simplifies your update logic, making it more readable and less prone to errors.
When not to use it
For trivial state updates, like toggling a single boolean or updating a top-level property, Immer can be overkill. A simple spread operator like {...state, isActive: false} is often more direct and performant for shallow updates. Immer adds a small overhead, so it provides the most benefit when the complexity of manual updates becomes a pain point.
One canonical example
Imagine updating a todo item in an array. Without Immer, you must clone the array and the specific object: const nextState = baseState.slice(); nextState[1] = { ...nextState[1], done: true };. With Immer, the logic is direct and clear: const nextState = produce(baseState, draft => { draft[1].done = true; });. You simply state your intent to change the property, and Immer handles the rest.
Interview question
How does Immer enable direct mutation of state while ensuring the original state remains immutable?
- a.It restricts mutations to only top-level properties, which are then shallow-copied to a new state object.
- b.It converts all mutable operations into a series of spread operators and object assignments internally.
- c.It uses a proxy "draft" object to track changes, then generates a new immutable state based on those recorded changes.Correct
- d.It performs a full deep clone of the state, so any mutations are applied to a separate copy.
Why? this is the answer
Immer's core mechanism involves providing a 'draft' object, which is a proxy. Any mutations applied to this draft are recorded by Immer, and once the recipe function completes, Immer uses these recorded changes to efficiently produce a new, immutable state, leaving the original state untouched. Option D is tempting but incorrect because Immer uses structural sharing, not always a full deep clone, for performance.
Just read this? Test yourself on what you have been reading.
Read the original → immerjs.github.io
- #state management
- #react
- #immutability
- #javascript
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on state management — each one lists the topics its interview covers.
See open roles