Deep Copy in JavaScript with structuredClone

Problem

The classic deep copy hack in JavaScript has some serious pitfalls.

const obj = {
  date: new Date(),
  func: () => 'hello',
  undef: undefined,
  regex: /test/gi,
};

const copy = JSON.parse(JSON.stringify(obj));
console.log(copy);
// { date: "2026-02-13T00:00:00.000Z", regex: {} }
// func and undef are gone, date became a string

Date gets converted to a string, undefined and functions are silently dropped, and circular references throw errors.

Solution

Use structuredClone. It’s supported in all modern browsers and Node.js 17+.

const original = {
  date: new Date(),
  nested: { a: 1, b: [2, 3] },
  set: new Set([1, 2, 3]),
  map: new Map([['key', 'value']]),
};

const copy = structuredClone(original);

copy.nested.a = 999;
console.log(original.nested.a); // 1 — original unchanged
console.log(copy.date instanceof Date); // true — Date preserved
console.log(copy.set instanceof Set); // true — Set preserved

Circular references work out of the box:

const obj = { name: 'test' };
obj.self = obj;

const copy = structuredClone(obj); // no error

Key Points

  • JSON.parse(JSON.stringify()) fails with Date, Set, Map, RegExp, and undefined
  • structuredClone correctly copies most built-in types
  • Functions, DOM nodes, and Symbol cannot be cloned even with structuredClone
  • No more need for lodash cloneDeep — native deep copy is here