immutable-js

Persistent immutable List, Map, Set, and Stack collections for JavaScript with structural sharing.

Library
npm
v5.1.9
33,035stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
92/100Excellent
Development Activity96
Maintenance96
Community76
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
87/100Excellent
Architecture88
Code Quality90
Innovation85
Learning Curve85

Immutable.js provides a set of persistent, immutable collection types for JavaScript — List, Map, OrderedMap, Set, OrderedSet, Stack, and Record — that mirror the native Array/Map/Set APIs while never mutating in place. Every write operation (set, push, delete, merge) returns a new collection instead of modifying the original, which makes state changes trivially detectable with reference equality (===) rather than deep comparison.

Under the hood, collections are implemented as hash-array-mapped tries (HAMTs) and vector tries, the same structural-sharing technique popularized by Clojure and Scala. This lets Immutable.js “copy” a collection of any size in O(log32 n) by sharing untouched branches of the trie between the old and new versions, instead of doing a full deep copy on every update. The library also ships a lazy Seq type that chains operations like map and filter without allocating intermediate collections, only evaluating when a terminal operation forces it.

With zero runtime dependencies, first-class TypeScript and Flow type definitions, and 33k+ GitHub stars, it remains one of the most widely used building blocks for predictable state management in React/Flux-style applications and anywhere reference-equality change detection matters.

What You Get

  • A full family of persistent collection types (List, Map, OrderedMap, Set, OrderedSet, Stack, Record) with APIs that closely mirror native Array/Map/Set
  • Structural sharing via hash-array-mapped tries and vector tries, so updates are O(log32 n) instead of full copies
  • Value equality via Immutable.is()/.equals(), plus reference-equality shortcuts (===) when an update produces an identical result
  • A lazy Seq type for chaining map/filter/etc. without allocating intermediate collections
  • A functional read/write API (get, getIn, setIn, updateIn, merge, mergeDeep) for working with plain JS values interchangeably with Immutable collections
  • First-class TypeScript and Flow type definitions bundled with the npm package
  • withMutations/transient batching to apply many changes efficiently before producing a single new immutable result

Common Use Cases

  • Modeling application state in React/Flux/Redux-style architectures where reference-equality change detection drives re-renders
  • Building undo/redo stacks or time-travel debugging where prior states must remain untouched and cheap to retain
  • Safely sharing nested data across modules or workers without defensive copying to prevent accidental mutation
  • Memoizing expensive computations keyed on collection identity, since unchanged updates return the same reference
  • Composing large nested records/maps (e.g. normalized API responses) with deep getIn/setIn/mergeDeep helpers

Under The Hood

Architecture The public API in src/Immutable.js re-exports a family of concrete collection types (List, Map, OrderedMap, Stack, Set, OrderedSet, Record, Seq) that all extend a shared Collection/CollectionImpl base implementing the iteration, equality, and transformation protocol once. Each concrete type (e.g. List.js, Map.js) layers its own persistent-trie storage on top of that shared base, so operations like map, filter, and reduce are implemented centrally in CollectionImpl.js/Operations.js while structural details (index-based vector tries for List, hashed tries for Map/Set) live in the type-specific files. Cross-cutting concerns are pulled into dedicated modules — TrieUtils.ts for shared trie constants and ref helpers, Hash.ts for value hashing, predicates/ for type guards (isList, isMap, etc.), and functional/ for the standalone get/setIn/merge-style functions that operate on both Immutable and plain JS values. This separation means adding a new collection type mostly means implementing trie storage plus reusing the shared iteration/equality machinery, and changing the core trie strategy would ripple through every concrete collection type.

Tech Stack The library is authored in a mix of TypeScript (type definitions, utilities like Hash.ts/TrieUtils.ts) and JavaScript (the performance-sensitive collection implementations such as List.js, Map.js, Operations.js), built with Rollup (resources/rollup-config.mjs) into CommonJS and ES module bundles plus a bundled .d.ts. It has zero runtime dependencies — devDependencies cover TypeScript, Flow, ESLint 9 with typescript-eslint, Prettier, Jest for unit tests, tstyche for type-level testing, fast-check for property-based testing, and a Next.js-based documentation website in website/. Package size is actively budgeted via size-limit against dist/immutable.es.js.

Code Quality Testing is extensive: 47+ files under __tests__/ (Jest) cover individual collection types (List.ts, Map.ts, OrderedMap.ts, Record.ts), cross-cutting concerns (Equality.ts, Conversion.ts, hash.ts), and property-based tests via fast-check, plus tstyche type tests for the TypeScript definitions and Flow’s own test suite under type-definitions/flow-tests. CI (.github/workflows/ci.yml) runs separate lint, type-check, and build-and-test jobs with a check-git-clean guard to catch generated-file drift. Code style is enforced via ESLint (flat config, typescript-eslint) and Prettier with lint/format npm scripts wired into CI. The mix of untyped legacy .js collection files alongside newer .ts modules shows an incremental TypeScript migration in progress rather than a from-scratch typed codebase.

What Makes It Unique Immutable.js’s distinguishing technical choice is its use of hash-array-mapped tries and vector tries for structural sharing — the same approach used by Clojure’s and Scala’s persistent collections — rather than the simpler copy-on-write array cloning many “immutable helper” libraries use. This gives near-O(1) amortized updates on large collections instead of O(n) copies, while still guaranteeing that untouched references remain byte-for-byte identical (enabling === shortcuts). Pairing that with a lazy Seq abstraction for chained operations, and a functional API layer that treats plain objects and Immutable collections uniformly, sets it apart from lighter-weight alternatives that only shallow-freeze or diff plain objects.

Used by 7 apps in this directory

Rust
67%
MIT

Bun

Developer Tools

95,895

An all-in-one JavaScript and TypeScript toolkit — one Rust-and-JavaScriptCore binary that replaces Node.js, npm, a bundler, and a test runner with faster equivalents.

View details
92
Repo Health
91
Technical
64
Dependency
Built with
Rust67%
C++19%
Updated yesterday
TypeScript
49%
AGPL 3.0

Grafana

Monitoring · Analytics

76,643

The open-source observability platform that unifies metrics, logs, and traces from any data source into dynamic, queryable dashboards.

View details
95
Repo Health
91
Technical
63
Dependency
Built with
TypeScript49%
Go45%
Updated today
Ruby
59%
AGPL 3.0

Mastodon

Social Media

50,274

Run your own federated social network on the open ActivityPub standard with no ads, no algorithms, and no corporate control over your community.

View details
95
Repo Health
81
Technical
70
Dependency
Built with
Ruby59%
TypeScript23%
Updated yesterday
Python
57%
Apache 2.0

MLflow

AI Development · Monitoring

27,837

The open source AI engineering platform for debugging, evaluating, monitoring, and optimizing production LLMs and agents at scale.

View details
97
Repo Health
86
Technical
67
Dependency
Built with
Python57%
TypeScript35%
Updated today
Clojure
73%
MPL 2.0

Penpot

Design Tools

59,670

Open-source design platform with GPU-accelerated canvas, native design tokens, and MCP-powered AI workflows for teams that ship fast.

View details
90
Repo Health
83
Technical
73
Dependency
Built with
Clojure73%
Updated 3 days ago
TypeScript
88%
MIT

Plasmic

CMS · Low Code Platforms · No Code Platforms

6,993

The open-source visual builder that lets teams design React apps and websites with drag-and-drop while integrating seamlessly with your codebase.

View details
81
Repo Health
78
Technical
64
Dependency
Built with
TypeScript88%
Updated yesterday
JavaScript
94%
Apache 2.0

swagger-ui

Developer Tools

29,002

Transform OpenAPI specifications into interactive, browser-based API documentation that developers and consumers can explore and test live.

View details
97
Repo Health
83
Technical
65
Dependency
Built with
JavaScript94%
Updated 2 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search