NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #807 most downloaded on npm
Create your next immutable state by mutating the current one
Last release 2 days ago
02 Oct 2026
Ships fairly regularly
a new release about every 4 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
2 versions withdrawn
withdrawn after publishing
10 years old
199 releases · first in 2016
throw on reads of a revoked Map or Set draft
do not record a deletion when a base value is written back
One column per quarter.
forward thisArg in the array-methods plugin
remove global var Iterator declaration conflicting with ESNext lib ( #1290 ) ( b00474e ), closes #1273
preserve structural sharing for no-op array-methods calls
key inserted array indices by name in the array-methods plugin
correct curried produceWithPatches return type ( #1249 ) ( a3be9df ), closes #1045
throw proper immer error when applyPatches path traverses null
draft relocated base refs after reverse/sort in array-methods plugin
Revert "prevent prototype pollution via constructor.prototype access (CVE-2026-XXXX) ( #1259 )" ( #1271 ) ( 4d3d6ff ), closes #1266 #1268 #1265
improve DraftMap.{entries,values}() compatibility #1228
undefined assigned to a prototype-inherited key gets dropped
prevent prototype pollution via constructor.prototype access (CVE-2026-XXXX)
update current and original typings to assert draft value is unwrapped
improve higher order type inference for WritableDraft
remove invalid curried producer type
handle nested proxies after spreading and inserting into an array
handle nested proxies after spreading and inserting into an array
## 11.1.3 (2025-12-29) ### Bug Fixes * recursive T for WritableDraft
## 11.1.2 (2025-12-29) ### Bug Fixes * bogus commit to retest release
This feature release adds a new optional "array method overrides" plugin that significantly speeds up array methods when accessing drafts.
This feature release adds a new optional "array method overrides" plugin that significantly speeds up array methods when accessing drafts.
As part of the recent performance optimization work, our benchmarks showed that all Proxy-based immutable update libraries were drastically slower than vanilla JS when calling both mutating and non-mutating array methods. After investigation, it turns out that an array method like arr.filter() causes the Proxy's get trap to trigger for every single item in the array. This in turn forces creation of a new Proxy and internal Immer metadata for every item, even though this was just a read operation and no items were being updated.
This release adds a new enableArrayMethods plugin that will override draft array methods to bypass the draft and directly operate on the underlying wrapped array instance. This significantly speeds up array operations.
When enabled, the plugin overrides these array methods:
push, pop, shift, unshift, splice, reverse, sortfilter, slice, concat, flat, find, findIndex, findLast, findLastIndex, some, every, indexOf, lastIndexOf, includes, join, toString, toLocaleStringOur benchmarks show that the overridden methods (plus the other perf changes in Immer 10.2 and 11.0) are 50-80% faster than the baseline behavior of Immer 10.1.
The plugin adds about 1.5-2K minified to Immer's bundle size.
It's important to note that the plugin does change the "safe to mutate a draft" semantics of Immer. Any of these methods that receives an array item as a callback argument will not automatically wrap that item in a Proxy!. That means that if you try to mutate an argument in a method such as filter, it will actually mutate the real underlying object, which will cause bugs in your app. This is an intentional design tradeoff. Semantically, all of these methods imply read-only access to array values, so if your code tries to mutate an array item in a callback, that is a bug in your code.
Note that this does not override map, flatMap, forEach, or reduce / reduceRight. Those methods do imply either side effects and potential mutations, or returning arbitrary values. Given that, we determined it was both safest and simplest to keep their behavior as-is.
See the Array Methods Plugin docs page for further details on the behavior of the overridden methods.
(dummy fix to release freeze fix per #1193)
Rewrite finalization system to use a callback approach instead of tree traversal
enable loose iteration by default
Simplify some iteration checks
Allow passing type to get/set utils to skip archetype lookup
Convert assigned_ to Map
Enable loose iteration
Replace recursive tree finalization with targeted callbacks
Ported Mutative's "finalization callback" approach as a more targeted and performant implementation for finalization compared to the existing recursive tree traversal approach:
Optimize Immer performance where possible, introduce setUseStrictIteration
Mark exports as pure, for better tree-shakability
performance: Make non-strict mode faster for classes. Addresses #1071 (53e3203). Immer 10.x solved slow iteration for plain JS objects. This update ap
setUseStrictShallowCopy("class_only") to revert to the old behavior. For more details see https://immerjs.github.io/immer/complex-objects#semantics-in-detailNothing published for this version
Nothing published for this version
production bundle was loaded incorrectly, fixes #1037
[breaking change] Immer 10 only supports modern browsers, that have support for Proxy, Reflect, Symbol and Map and Set.
Proxy, Reflect, Symbol and Map and Set.createDraft and finishDraft.enableES5(), you SHOULD NOT upgrade Immer. enableES5 has been removed.produce is no longer exposed as the default export. This improves eco system compatibility, and makes sure that there is only one correct way of doing thingsenableAllPlugins has been removed, use enablePatches(); enableMapSet() insteadlength property, in accordance with JSON spec. Thanks kshramt for implementing this in #964!Overall, there is a rough performance increase of 33% for Immer (and in some cases significantly higher), and the (non gzipped) bundle size has reduced from 16 to 11.5 KB, while the the minimal gzipped import of just produce has remained roughly the same at 3.3 KB.
For more details, see #1015
enableES5() call, don't migrateuseStrictShallowCopy(true) at startupimport produce from "immer" with import {produce} from "immer"enableAllPlugins() with enablePatches(); enableMapSet(); to be more specific and smoothen future migrations.createDraft instead. Roughly:const newState = await produce(oldState, recipe)
// becomes
const draft = createDraft(oldState)
await recipe(draft)
const newState = finishDraft(draft)
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
ensure type exports is first in package.json export declaration
patching maps failed when using number keys
don't freeze drafts returned from produce if they were passed in as draft
## 9.0.17 (2023-01-02) ### Bug Fixes * special case NaN in setter
protect isDraftable against undefined constructor
Add "types" to exports for TypeScript 4.7
Use .esm.js module for backwards compatibility with old build tools
produceWithPatches should not wrap result in Immutable, fixes #850, #881
incorrect patches for delete on arrays. Fixes #879
No patches being generated for root primitive replacements. Fixes #888
make sure produceWithPatches accepts promises
immerjs#876 Ensure empty patch set for atomic set+delete on Map
Append to array when key is "-"
security: Follow up on CVE-2020-28477 where path: [["__proto__"], "x"] could still pollute the prototype
## 9.0.5 (2021-07-05) ### Bug Fixes * release missing dist/ folder
Better applyPatches type (#810) (09ac097), closes #809
isPlainObject: add quick comparison between input and Object to short-circuit taxing Function.toString invocations
Your coding agent can read these notes before it upgrades. Set up the MCP server →