Immer
Create your next immutable state by mutating the current one.
Repository Health
Technical Analysis
Immer is a small, zero-dependency JavaScript library that lets you write the next immutable state by mutating a temporary “draft” instead of hand-rolling spreads, Object.assign, or deep clones. It wraps your base state in an ES6 Proxy, records exactly which branches of the tree you touched inside a recipe function, and produces a new state object that shares every untouched branch with the original — giving you both natural mutation syntax and full structural-sharing immutability guarantees.
Because the API surface is a single produce(base, recipe) call (plus a curried form for reducers), Immer drops into Redux reducers, React useState/useReducer updates, and any other place immutable updates are required without changing how the surrounding code reads. Optional plugins add Map/Set support, JSON patch generation, and array-method interception, keeping the core bundle minimal for consumers who don’t need them.
What You Get
- A single
produce(base, recipe)function that returns a new immutable state from mutation-style code, plus a curried form for use directly as a Redux reducer produceWithPatches,applyPatches, and patch listeners for recording and replaying granular JSON-patch-style changes (undo/redo, time travel, network sync)createDraft/finishDraftfor manual draft lifecycles outside the callback-basedproduceflow- Opt-in plugins —
enableMapSetfor native Map/Set drafting,enablePatchesfor patch generation,enableArrayMethodsfor optimized array method interception — kept out of the core bundle until enabled - First-class TypeScript types (
Draft,WritableDraft,Immutable) that infer the mutable draft shape from your immutable state type and back again current()andoriginal()helpers to inspect in-progress drafts or the untouched base value from inside a recipe
Common Use Cases
- Writing Redux or
useReducerreducers as if directly mutating state, while Immer guarantees the returned value is a new immutable object - Updating deeply nested React component state (nested objects/arrays) in a single
setStatecall without manual spreading at every level - Building undo/redo or collaborative-editing features on top of the patches Immer generates for every producer call
- Simplifying form-state or normalized-store libraries that need copy-on-write semantics without hand-writing structural sharing
Under The Hood
Architecture — src/immer.ts exports the public API bound to a singleton Immer instance whose produce/produceWithPatches/createDraft/finishDraft/applyPatches methods live in src/core/immerClass.ts. Calling produce() checks isDraftable(base), opens a scope via enterScope (src/core/scope.ts), and creates a root proxy through the createProxy dispatcher, which delegates to proxyMap_/proxySet_ (src/plugins/mapset.ts) for Map/Set or to createProxyProxy (src/core/proxy.ts) for plain objects and arrays. The object/array traps in proxy.ts implement copy-on-write: get lazily creates child proxies only for properties actually read, set/deleteProperty call prepareCopy() to shallow-copy a branch the first time it’s touched and markChanged() to bubble a modified_ flag up to every ancestor. After the recipe returns, finalization walks the scope’s drafts and swaps in copy_ only where modified_ is true, leaving everything else pointing at the original base_ references (structural sharing), then optionally freezes the result and emits patches through the patches plugin if a listener was supplied.
Tech Stack — The library is authored entirely in TypeScript (src/) with zero runtime dependencies, built by tsup (tsup.config.ts) into CJS, ESM, and a legacy ESM bundle plus .d.ts declarations, as declared in package.json’s exports map. Tests run on Vitest (vitest.config.ts for source, vitest.config.build.ts to re-run the suite against the built artifacts), with a separate Flow type-check pass (yarn test:flow) for consumers still on Flow, and semantic-release drives versioned publishing from the main branch.
Code Quality — __tests__/produce.ts alone runs 844 lines of scenario coverage (curried producers, Map/Set drafting, patches, class instances, frozen input, array mutation edge cases), complemented by redux.ts for reducer-integration tests, spec_ts.ts/type-external.ts for compile-time type assertions, a dedicated flow/ suite, and both dev- and prod-mode snapshot fixters (__snapshots__, __prod_snapshots__) that pin the numeric die() error codes used in production builds. Coveralls integration tracks coverage over time, reflecting the rigor expected of a dependency this widely embedded in other libraries’ reducers.
API Design — The public surface is deliberately tiny: produce(base, recipe) is the only call most consumers ever need, with a curried variant that drops straight into useReducer/Redux without a wrapper. Escape hatches (original(), current(), no-op castDraft/castImmutable for type coercion) cover the cases where you need to read outside the draft. Plugins are opt-in via explicit enableMapSet()/enablePatches()/enableArrayMethods() calls rather than bundled by default, and the TypeScript types automatically flip an Immutable<T> state type into a mutable Draft<T> inside the recipe and back — removing a whole class of manual type-casting that other immutable-update approaches require.
Used by 52 apps in this directory
twenty
CRM
The open-source CRM you build, ship, and version like the rest of your stack — with customizable objects, AI agents, and a TypeScript SDK.
Typebot
AI Assistants · AI Development · Developer Tools
Build sophisticated chatbots visually, embed them anywhere without iframes, and own your data — fully self-hostable with a modular block system and 30+ integrations.
Umami
Analytics
Privacy-first web analytics that respects your users — self-hosted, cookieless, and GDPR compliant out of the box.
Unleash
Ab Testing Experimentation · Developer Tools · Devops
The open-source feature management platform that lets you ship code to production and control who sees it — without redeploying.
Vibe Kanban
AI Agents · AI Code Assistants · Project Management
A kanban board for planning work and dispatching Claude Code, Codex, Gemini CLI, and eight other coding agents into isolated git worktrees, then reviewing and merging their diffs from one UI.
Webstudio
Design Tools · No Code Platforms
Open source visual development platform with complete CSS control, headless CMS integration, and full infrastructure ownership
Wire
Collaboration · Team Chat · Video Conferencing
Open source end-to-end encrypted messaging for teams and enterprises — self-host for complete control over your communications and data.