Skip to content

deepClone

High-fidelity deep clone. Import from @pivanov/utils/tools or @pivanov/utils.

ts
import { deepClone } from '@pivanov/utils/tools';

const copy = deepClone(original);

What's handled

TypeCloning behavior
Primitives (string, number, bigint, symbol, boolean)Returned as-is
null / undefinedReturned as-is
Array (dense + sparse)New array, elements recursively cloned
Plain objectNew object, properties recursively cloned
Class instanceNew instance, prototype preserved, properties recursively cloned
DateNew instance with the same time
RegExpNew instance with same source + flags
Map / SetNew collection, entries recursively cloned
ArrayBufferByte-wise copy
TypedArray (Uint8, Int32, etc.)New instance, new underlying buffer
DataViewNew instance, new underlying buffer
Buffer (Node)Buffer.from(...) copy
Getters / settersDescriptors preserved as accessors
Symbol-keyed properties (enumerable)Copied
Non-enumerable propertiesDropped
Circular referencesPreserved via internal WeakMap

Examples

ts
import { deepClone } from '@pivanov/utils/tools';

// Nested plain objects
const copy = deepClone({ nested: { array: [1, 2, { value: 3 }] } });

// Preserves class prototypes
class User {
  constructor(public name: string) {}
  greet() { return `hi ${this.name}`; }
}
const original = new User('Ada');
const cloned = deepClone(original);
cloned instanceof User;   // true
cloned.greet();           // 'hi Ada'

// Circular references
const obj: any = { value: 1 };
obj.self = obj;
const circ = deepClone(obj);
circ.self === circ;       // true

// Maps, Sets, Dates, TypedArrays
deepClone(new Map([['a', 1]]));
deepClone(new Set([1, 2, 3]));
deepClone(new Date());
deepClone(new Uint8Array([1, 2, 3]));

Relationship to structuredClone

The global structuredClone (Node 17+, all modern browsers) covers a subset of what deepClone does:

FeaturestructuredClonedeepClone
Date, Map, Set, RegExp, TypedArrays
Circular references
Class prototypes preserved
Getters/setters preserved✗ (evaluated to data)
Symbol-keyed properties
Node Buffer preserved✗ (becomes Uint8Array)
Functionsthrowsthrows

If you only need the first three rows, structuredClone is fine and built in. Reach for deepClone when the richer semantics matter.

MIT License | Made by Pavel Ivanov