4 min read
I bumped one user score in a 1,000-user tree on this box: Immer 11.1.21 median about 86 us per produce, Mutative 1.3.0 about 3 us. Both kept structural sharing on untouched branches. Gzip favored Immer slightly (5.3 KB vs 6.5 KB).
Short answer: pick Mutative when produce cost shows up in profiles. Pick Immer when you want the smaller gzip and the wider ecosystem. No affiliate links in this post.
| Path (5,000 updates, median of 9) | Immer | Mutative |
|---|---|---|
| Bump one score (us per update) | 86.2 | 3.0 |
| Bump one score (ops/s) | 11,599 | 338,079 |
| Deep edit (us per update) | 101.1 | 8.7 |
| Deep edit (ops/s) | 9,892 | 115,347 |
Mutative won the wall-clock race on both paths. Structural sharing matched: after editing users[0], users[1] kept the same object reference in both libraries. Compiler-side cost notes sit next to SWC vs esbuild/Babel when the transform pipeline is the bottleneck instead.
| Browser build (esbuild minify) | Minified | gzip -9 |
|---|---|---|
| immer (produce, enableMapSet) | 13,964 B | 5,313 B |
| mutative (create, rawReturn) | 19,615 B | 6,512 B |
Immer was smaller on this import set. Disk trees were about 1.1 MB for immer against 908 KB for mutative. Track shipped weight with size-limit vs bundlesize. Schema/validation choices next to reducers: Zod vs Valibot.
| Situation | My pick |
|---|---|
| Hot produce loop in a profile | Mutative |
| Smallest gzip for produce+Map helpers | Immer |
| Already on Redux Toolkit / Immer docs | Immer |
| New greenfield immutable updates | Mutative |
| Bundle budget under about 6 KB gzip | Immer |
Bottom line: Mutative 1.3.0 took about 3 us per bump against Immer 11.1.21 at about 86 us on a 1,000-user tree, while Immer shipped 5.3 KB gzip against Mutative at 6.5 KB. Who should not switch: apps whose Immer produces are rare and already under budget — the API is familiar and the gzip win is real. Lint after a swap with Biome vs ESLint/Prettier. Dead-code check: knip vs depcheck. Test runner: Jest vs Vitest.
How this was made: I installed Immer and Mutative on the ShopperCove box, timed produce/create loops on a 1,000-user fixture, measured esbuild minify+gzip sizes, verified structural sharing, and recorded the JSON. The write-up was drafted with AI help and checked against that output.
Lab evidence
Hands-on on ShopperCove box 6 Oct 2026 ~00:56-00:57 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 22.20.0). immer 11.1.21 vs mutative 1.3.0, esbuild 0.28.2. Fixture /workspace/bench-immer-mutative/: meta + 1,000 users (score, tags[], nested profile). Bump-one: 5,000 produce/create x 9 rounds after warm. Deep: edit profile.city, push tag, bump meta.version. Structural-share check on untouched user refs. Medians: bump 86.2 vs 3.0 us/update; deep 101.1 vs 8.7 us; gzip 5,313 vs 6,512 B. Disk ~1.1 MB vs ~908 KB. Raw: res-bench.json, res-bundle.json. Not tested: Map/Set patches, RTK wiring, patches/inversePatches, freeze options, React bindings, real browsers. No affiliate.