Skip to content

Repository files navigation

is-deep-immutable

TypeScript-first utility to check deep immutability in JavaScript objects

npm versionlicense

Tiny zero-dependency library to detect and assert deep immutability.
Works with plain objects, arrays, Maps, Sets, Dates, and nested structures.
Ships with full TypeScript support and ESM-only build.


Features

  • TypeScript-first — strong type guards like value is DeepImmutable<T>
  • Deep immutability checks — recursive checks across nested structures
  • Helpful errorsassertImmutable shows the exact path of mutability
  • Zero dependencies — small, fast, tree-shakable
  • Modern packaging — ESM, Node 18+, Deno, Bun

Install

npm install is-deep-immutable

Usage

import{isDeepImmutable,assertImmutable}from'is-deep-immutable';constdata={users: [{id: 1,name: 'Alice'}],metadata: newMap([['version','1.0.0']]),tags: newSet(['production'])};// Check if deeply immutableconsole.log(isDeepImmutable(data));// false// Manually freeze for testingconstfrozen=Object.freeze({users: Object.freeze(data.users.map(u=>Object.freeze(u))),metadata: Object.freeze(data.metadata),tags: Object.freeze(data.tags)});console.log(isDeepImmutable(frozen));// true// Assert immutability (throws if not)assertImmutable(frozen);// ✓ passesassertImmutable(data);// ✗ throws with detailed path

API

isDeepImmutable(value): boolean

Type guard that checks if a value is deeply immutable. Returns true for primitives and recursively frozen objects.

isDeepImmutable(42);// trueisDeepImmutable('hello');// true isDeepImmutable({});// falseisDeepImmutable(Object.freeze({}));// true

assertImmutable(value): asserts value is DeepImmutable<T>

Asserts that a value is deeply immutable. Throws with the exact path of mutability if not.

assertImmutable({mutable: true});// Error: Value is not immutable at path "root": Object is not frozenassertImmutable({nested: {mutable: true}});// Error: Value is not immutable at path "nested": Object is not frozen

TypeScript Support

Full TypeScript support with the DeepImmutable<T> utility type:

typeDeepImmutable<T>=Textends(infer U)[]
? ReadonlyArray<DeepImmutable<U>>
: TextendsMap<infer K, infer V>
? ReadonlyMap<DeepImmutable<K>,DeepImmutable<V>>
: TextendsSet<infer U>
? ReadonlySet<DeepImmutable<U>>
: Textendsobject
? {readonly[KinkeyofT]: DeepImmutable<T[K]>}
: T;

Supported Types

  • Primitives: string, number, boolean, null, undefined, symbol, bigint
  • Objects: Plain objects with recursive property checking
  • Arrays: Recursive element checking
  • Maps: Key and value immutability checking
  • Sets: Element immutability checking
  • Dates: Treated as immutable when frozen
  • Circular references: Handled safely without infinite recursion

License

MIT

About

Tiny, zero-dependency, TypeScript-first utility that checks, asserts, and enforces deep immutability in JavaScript objects.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Contributors

Languages