Immer — Immutable State with Mutable Syntax
Immer lets you create the next immutable state by mutating the current one. Write mutating code as if it were normal JS and Immer produces a new immutable object via structural sharing. Built into Redux Toolkit and Zustand.
Installation agent prête
Cet actif peut être installé après choix du runtime, vérification du plan et exécution de la commande adaptée.
npx -y tokrepo@latest install 3ae90d2f-35aa-11f1-9bc6-00163e2b0d79 --target codexÀ exécuter après confirmation du plan en dry-run.
What it is
Immer is a JavaScript library that simplifies immutable state management. Instead of writing spread operators and nested object copies, you write normal mutable code inside a produce function. Immer intercepts your mutations via a Proxy, applies structural sharing, and returns a new immutable object.
Immer is the state management engine behind Redux Toolkit. If you use createSlice or createReducer in Redux Toolkit, you are already using Immer. It targets any JavaScript or TypeScript project that needs immutable data patterns without the verbosity.
How it saves time or tokens
Immutable updates in plain JavaScript are verbose and error-prone. Updating a nested property requires spreading every level of the object tree. Immer eliminates this boilerplate: you mutate the draft object directly, and Immer handles the rest. This reduces both code size and the chance of missing a spread operator.
For AI-generated code, Immer produces simpler, more readable state updates that are easier for LLMs to generate correctly.
How to use
- Install Immer:
npm install immer
- Use the
producefunction:
import { produce } from 'immer';
const state = {
users: [
{ id: 1, name: 'Alice', tags: ['admin'] },
{ id: 2, name: 'Bob', tags: ['user'] }
]
};
const nextState = produce(state, draft => {
draft.users[0].tags.push('superadmin');
draft.users.push({ id: 3, name: 'Charlie', tags: ['user'] });
});
// state is unchanged
// nextState has the updates with structural sharing
- In Redux Toolkit, Immer is built in:
const userSlice = createSlice({
name: 'users',
initialState: { list: [] },
reducers: {
addUser(state, action) {
// This looks like a mutation but Immer handles it
state.list.push(action.payload);
}
}
});
Example
import { produce, enableMapSet } from 'immer';
// Enable Map and Set support
enableMapSet();
const state = new Map([['a', 1], ['b', 2]]);
const next = produce(state, draft => {
draft.set('c', 3);
draft.delete('a');
});
// state: Map { 'a' => 1, 'b' => 2 }
// next: Map { 'b' => 2, 'c' => 3 }
Related on TokRepo
- AI Tools for Coding -- Developer tools and libraries for AI-assisted development
- Featured Workflows -- Discover more curated development resources
Common pitfalls
- Do not return a value from the produce callback if you also mutate the draft. Either mutate the draft or return a new value, never both. Immer throws an error if you do both.
- Map and Set support requires calling
enableMapSet()before using produce with Maps or Sets. Without it, Immer ignores Map/Set mutations. - Immer uses Proxies, which have a small performance overhead. For hot paths processing thousands of updates per second, benchmark against manual immutable updates.
Questions fréquentes
No. Immer is the immutability library that Redux Toolkit uses internally. You can use Immer standalone in any JavaScript project, with React useState, with MobX, or anywhere you need immutable state updates.
Yes. Immer has full TypeScript support with correct type inference. The produce function preserves the type of your state object, and draft types are automatically mutable versions of your immutable types.
When Immer creates the next state, it only copies the objects that changed. Unchanged parts of the tree are shared by reference with the previous state. This is memory-efficient and enables fast equality checks via reference comparison.
Yes. That is where Immer provides the most value. Instead of spreading five levels deep to update a nested property, you mutate the draft directly: `draft.level1.level2.level3.value = 'new'`.
Immer adds a small overhead due to Proxy creation. For typical UI state updates, the overhead is negligible. For bulk operations processing thousands of objects, consider using `produce` once for the entire batch rather than calling it per item.
Sources citées (3)
- Immer GitHub Repository— Immer creates immutable state via Proxy-based draft objects
- Redux Toolkit Documentation— Immer is built into Redux Toolkit as the default immutability layer
- Immer Documentation— Structural sharing minimizes memory usage for state updates
En lien sur TokRepo
Fil de discussion
Actifs similaires
Redux — Predictable Global State Management for JS Apps
Redux is the original predictable state container for JavaScript apps. Modern Redux uses Redux Toolkit (RTK) which reduces boilerplate 80% and includes RTK Query for server state. Still the standard for large-scale React apps.
Zustand — Bear-Sized State Management for React
Zustand is a small, fast, and scalable bearbones state-management solution for React. A cozy alternative to Redux with a simple hooks API, no providers needed, and first-class TypeScript support.
NgRx — Reactive State Management for Angular
Redux-inspired state management framework built with RxJS for Angular applications.
Nanostores — Tiny State Manager for Any Framework
Framework-agnostic state management in under 1kB with first-class support for React, Vue, Svelte, and vanilla JS.