The structuredClone() function
structuredClone() is a built-in JavaScript function that creates a deep clone of any value, including objects, arrays, Map, Set, dates, RegExp, Blob, File, ArrayBuffer and even cyclic references. The result is a completely independent copy, not another reference to the same object.
Theory
TL;DR
structuredClone(value)returns a new, independent deep clone of the value.- It preserves
Date,Map,Set,RegExp,Error,ArrayBuffer,Blob,File,undefined,NaNandInfinity. - It handles cyclic references correctly, where
JSON.stringify()throws. - It cannot copy functions, class methods or DOM elements, those raise a
DataCloneError. - A second argument
{ transfer: [...] }lets you hand over a binary buffer instead of copying it. - It works in modern browsers and in Node.js from version 17 onwards.
Quick example
const user = {
name: "Tim",
age: 25,
skills: ["JS", "React"],
meta: { active: true },
};
const copy = structuredClone(user);
copy.meta.active = false;
console.log(user.meta.active); // true, the original is unchangedHere structuredClone() produced a new copy, not a reference to the same object, unlike the shallow copy { ...user }, where meta would still be shared.
Syntax
const clone = structuredClone(value);valueis what you want to clone;- the function returns a new, fully copied and independent object.
Cloning is recursive: every nested object, array or collection gets its own copy too, so you can mutate the clone at any depth.
The main difference from JSON.parse(JSON.stringify(...))
Deep copying used to be written like this:
const copy = JSON.parse(JSON.stringify(obj));But that approach has a lot of limitations:
| Data type | JSON method | structuredClone |
|---|---|---|
Date | becomes a string | kept as a Date |
Map, Set | lost | copied |
undefined | disappears | preserved |
RegExp, Error | lost | preserved |
NaN, Infinity | become null | preserved |
| Cyclic references | throws | supported |
In other words, structuredClone() is the reliable and safe deep clone that supports all of these types.
Example with cyclic references
const obj = {};
obj.self = obj; // a cyclic reference
const clone = structuredClone(obj);
console.log(clone.self === clone); // truePreviously this kind of cloning would simply throw. The structured clone algorithm remembers the objects it has already copied, so re-entering the same node turns into a reference inside the copy instead of infinite recursion.
Cloning with transfer of binary data
structuredClone takes a second argument, an options object, that lets you transfer (rather than copy) certain objects, for example an ArrayBuffer.
const buffer = new ArrayBuffer(8);
const clone = structuredClone(buffer, { transfer: [buffer] });
console.log(buffer.byteLength); // 0, the original was transferred and detached
console.log(clone.byteLength); // 8, the data now belongs to the cloneThis behaves like transferable objects in postMessage: the memory is not copied, it changes owner, so the operation stays cheap even for large buffers.
Where it works, and a summary
The function is supported in every modern browser and in Node.js from version 17:
structuredClone({ test: true }); // works in Node.js 17+| Item | Description |
|---|---|
| What it does | Deep clones a value of almost any type |
| Returns | A fully independent copy |
| Supports | Date, Map, Set, RegExp, ArrayBuffer, cyclic references |
| Does not support | Functions, DOM elements |
| Compatibility | Modern browsers and Node.js 17+ |
| Equivalent to | A safe alternative to JSON.parse(JSON.stringify()) |
Common mistakes
- Expecting methods to be copied. Functions are not cloneable:
structuredClone({ fn() {} })throws aDataCloneError. A class instance turns into a plain data object with no prototype. - Cloning DOM nodes.
structuredClone(document.body)also throws aDataCloneError, document nodes are not serialisable by this algorithm. - Confusing it with a shallow copy.
{ ...obj }andObject.assign({}, obj)copy only the top level, nested objects stay shared. - Forgetting about the prototype. The clone gets a plain
Object.prototype, socopy instanceof Userreturnsfalse. - Relying on getters and setters surviving. They are evaluated once and the clone receives the resulting value as an ordinary property.
- Using it in an old runtime. Node.js 16 and below do not have the function, so a polyfill or a hand-written implementation is required there.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.