structuredClone()
structuredClone(value) Deep copy of input value · Added in vES2021 · Updated March 17, 2026 · Global Functions The structuredClone() function creates a deep copy of a JavaScript value using the structured clone algorithm. Unlike JSON.parse(JSON.stringify()), it handles complex data types including Maps, Sets, Dates, RegExps, and circular references.
Syntax
structuredClone(value)
structuredClone(value, options)
Parameters
| Parameter | Type | Description |
|---|---|---|
value | any | The object to be cloned. Can be any structured-cloneable type. |
options | object | Optional. An object with a transfer property containing an array of transferable objects. |
Transfer Options
The transfer option moves (rather than clones) specified transferable objects, making the original unusable. This enables zero-copy data transfer between contexts like web workers or IndexedDB:
const buffer = new ArrayBuffer(16);
const cloned = structuredClone({ buffer }, { transfer: [buffer] });
// buffer.byteLength is now 0
Transferable objects include ArrayBuffer, TypedArray, MessagePort, and ImageBitmap.
Return Value
A deep copy of the original value. If the value contains circular references, they are preserved in the clone.
Examples
Basic Clone
const original = {
name: "Alice",
data: [1, 2, 3],
metadata: new Map([["key", "value"]])
};
const clone = structuredClone(original);
clone.name = "Bob";
clone.data.push(4);
console.log(original.name); // "Alice"
console.log(clone.name); // "Bob"
console.log(original.data); // [1, 2, 3]
console.log(clone.data); // [1, 2, 3, 4]
Cloning with Circular References
const original = { name: "circular" };
original.self = original;
const clone = structuredClone(original);
console.log(clone.name); // "circular"
console.log(clone.self === clone); // true
Transferring ArrayBuffers
const uInt8Array = new Uint8Array([1, 2, 3]);
const transferred = structuredClone(uInt8Array, {
transfer: [uInt8Array.buffer]
});
console.log(uInt8Array.byteLength); // 0
console.log(transferred); // Uint8Array [1, 2, 3]
Error Handling
structuredClone() throws a DataCloneError when it encounters unclonable data:
const obj = { fn: () => {} };
try {
structuredClone(obj);
} catch (e) {
console.log(e.name); // "DataCloneError"
console.log(e.message); // "...could not be cloned."
}
Limitations
structuredClone() cannot clone:
- Functions — throws
DataCloneError - DOM nodes — throws
DataCloneError - Property descriptors, setters, and getters — metadata is lost
- RegExp.lastIndex — the property is not preserved
- Class private fields
- Prototype chain — only own enumerable properties are copied
- WeakMap and WeakSet — throws
DataCloneError
Symbol Behavior
- Primitive Symbol values cannot be cloned (throws
DataCloneError) - Symbol keys in objects are preserved as property keys
const sym = Symbol("test");
const obj = { [sym]: "value", regularKey: "data" };
const clone = structuredClone(obj);
console.log(Object.getOwnPropertySymbols(clone)); // [Symbol(test)]
console.log(clone[sym]); // "value"
Error Objects
Standard error types (Error, TypeError, RangeError, etc.) are cloned correctly. However, custom Error subclasses lose their constructor name:
class CustomError extends Error {
constructor(message) {
super(message);
this.name = "CustomError";
}
}
const error = new CustomError("oops");
const cloned = structuredClone(error);
console.log(cloned.name); // "Error" — name is forced to "Error"
See Also
- JSON.parse() — parse JSON strings
- JSON.stringify() — convert values to JSON
- Object.assign() — shallow copy and merge objects