Installation

Immer can be installed as a direct dependency, and will work in any ES5 environment:

  • Yarn: yarn add immer
  • NPM: npm install immer
  • CDN: Exposed global is immer
    • Unpkg: <script src="https://unpkg.com/immer"></script>
    • JSDelivr: <script src="https://cdn.jsdelivr.net/npm/immer"></script>
    • โš ๏ธ When using a CDN, it is best to check the url in your browser and see what version it resolves to, so that your users aren't accidentally served a newer version in the future when updates are release. So use an url like: https://unpkg.com/immer@6.0.3/dist/immer.umd.production.min.js instead. Substitute production.min with development in the URL for a development build.

Pick your Immer version#

This section only applies to version 6 and later

To make sure Immer is as small as possible, features that are not required by every project has been made opt-in, and have to be enabled explicitly. This ensures that when bundling your application for production, unused features don't take any space.

The following features can be opt-in to:

FeatureDescriptionMethod to call
ES 5 supportIf your application needs to be able to run on older JavaScript environments, such as Internet Explorer or React Native, enable this feature.enableES5()
ES2015 Map and Set supportTo enable Immer to operate on the native Map and Set collections, enable this featureenableMapSet()
JSON Patch supportImmer can keep track of all the changes you make to draft objects. This can be useful for communicating changes using JSON patchesenablePatches()
All of the aboveUnsure what features you need? We recommend to enable all of the features above by default on new projects. Premature optimization of a few KB might not be worth the initial trouble. Also, enabling or disabling features doesn't impact the performance of Immer itselfenableAllPlugins()

For example, if you want to use produce on a Map, you need to enable this feature once during the start of your application:

// In your application's entrypoint
import {enableMapSet} from "immer"
enableMapSet()
// ...later
import produce from "immer"
const usersById_v1 = new Map([
["michel", {name: "Michel Weststrate", country: "NL"}]
])
const usersById_v2 = produce(usersById_v1, draft => {
draft.get("michel").country = "UK"
})
expect(usersById_v1.get("michel").country).toBe("NL")
expect(usersById_v2.get("michel").country).toBe("UK")

Vanilla Immer kicks in at ~3KB gzipped. Every plugin that is enabled adds < 1 KB to that. The breakdown is as follows:

Import size report for immer:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ (index) โ”‚ just this โ”‚ cumulative โ”‚ increment โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ import * from 'immer' โ”‚ 5662 โ”‚ 0 โ”‚ 0 โ”‚
โ”‚ produce โ”‚ 3100 โ”‚ 3100 โ”‚ 0 โ”‚
โ”‚ enableES5 โ”‚ 3761 โ”‚ 3770 โ”‚ 670 โ”‚
โ”‚ enableMapSet โ”‚ 3885 โ”‚ 4527 โ”‚ 757 โ”‚
โ”‚ enablePatches โ”‚ 3891 โ”‚ 5301 โ”‚ 774 โ”‚
โ”‚ enableAllPlugins โ”‚ 5297 โ”‚ 5348 โ”‚ 47 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
(this report was generated by npmjs.com/package/import-size)

Immer on older JavaScript environments?#

By default produce tries to use proxies for optimal performance. However, on older JavaScript engines Proxy is not available. For example, when running Microsoft Internet Explorer or React Native (if < v0.59 or when using the Hermes engine on React Native < 0.64) on Android. In such cases, Immer will fallback to an ES5 compatible implementation which works identically, but is a bit slower.

Since version 6, support for the fallback implementation has to be explicitly enabled by calling enableES5().