JavaScript structuredClone()

The structuredClone() web API creates a deep copy of supported JavaScript values. Unlike object spread or Object.assign(), it recursively clones nested data. It also preserves useful built-in types such as Date, Map, Set, ArrayBuffer, and typed arrays.

The method is widely available in modern browsers and web workers. It is a host API rather than part of the ECMAScript language, so check the JavaScript runtime when code must run outside a browser.

Create a Deep Clone

Pass the value to structuredClone(). Editing a supported nested value in the clone does not alter the original object.

Run this example:

<button id="clone">Clone and edit</button>
<pre id="output"></pre>

<script>
const original = {
  customer: "Aarav",
  placedAt: new Date("2026-08-13"),
  items: [{ name: "Notebook", quantity: 1 }]
};

// Create an independent deep clone.
const copy = structuredClone(original);
copy.customer = "Olivia";
copy.items[0].quantity = 3;

console.log(original.items[0].quantity); // 1
console.log(copy.placedAt instanceof Date); // true
</script>

Shallow Copy and Deep Clone

Spread syntax copies only the top level. Nested objects still refer to the same underlying values. A structured clone recursively duplicates supported nested values.

const original = { profile: { city: "Pune" } };

const shallow = { ...original };
shallow.profile.city = "London";
console.log(original.profile.city); // London

const deep = structuredClone(original);
deep.profile.city = "New York";
console.log(original.profile.city); // London
Approach Nested data Important limits
Spread syntax Shares nested references Copies enumerable own properties at one level
JSON conversion Creates nested copies for JSON data Loses or rejects several JavaScript values and cannot handle cycles
structuredClone() Deep-clones supported types Rejects functions, DOM nodes, symbols, and other non-cloneable data

Clone Built-In Data Types

JSON conversion turns Date values into strings and does not preserve Map or Set as those types. Structured cloning supports them directly.

const settings = {
  updatedAt: new Date(),
  roles: new Set(["editor", "reviewer"]),
  scores: new Map([["Aarav", 92], ["Olivia", 88]]),
  pattern: /article/gi
};

const copy = structuredClone(settings);

// Supported built-ins keep their useful type.
console.log(copy.updatedAt instanceof Date); // true
console.log(copy.roles instanceof Set);      // true
console.log(copy.scores instanceof Map);     // true

Clone Circular References

The structured clone algorithm tracks references it has already visited, so circular object graphs can be copied safely.

const category = { name: "JavaScript" };
category.parent = category;

const copy = structuredClone(category);

// The copied cycle points to the copied object.
console.log(copy !== category);       // true
console.log(copy.parent === copy);    // true

Transfer Large Buffers

The optional transfer list moves the resource owned by a transferable object instead of duplicating it. Transferring an ArrayBuffer detaches the original buffer, so its byte length becomes zero.

const bytes = new Uint8Array([10, 20, 30, 40]);

const moved = structuredClone(bytes, {
  // Transfer the buffer owned by the typed array.
  transfer: [bytes.buffer]
});

console.log(bytes.byteLength); // 0: original buffer is detached
console.log(moved[2]);         // 30

Transfer the underlying buffer rather than the typed-array view. Use transfer only when the source must no longer use that resource.

Handle DataCloneError

If any part of the value is not serializable by the structured clone algorithm, the method throws a DataCloneError DOMException.

const value = {
  title: "Report",
  format() { return this.title.toUpperCase(); }
};

try {
  // Functions cannot be structured-cloned.
  const copy = structuredClone(value);
} catch (error) {
  if (error.name === "DataCloneError") {
    console.error("Remove non-cloneable values before copying.");
  }
}

Understand What Is Not Preserved

  • Functions and DOM nodes cannot be cloned.
  • Symbols are not structured-cloneable values.
  • Custom property descriptors, getters, and setters are not reproduced as descriptors.
  • The prototype chain of a user-defined class is not duplicated as class behavior.
  • The lastIndex state of RegExp values is not preserved.
  • Private class elements are not cloned.

A structured clone copies data, not application behavior. Convert class instances to plain data or provide an explicit reconstruction method when the prototype and methods matter.

Clone Only When Isolation Is Needed

Deep cloning a large graph takes time and memory. Do not clone automatically whenever data is passed to another function. Prefer immutable updates, selective copying, or a purpose-built data model when only part of the graph needs isolation.

Where Structured Cloning Is Used

The same algorithm supports data exchange with web workers through postMessage(), storage in IndexedDB, history state, and other browser APIs. The receiving context gets duplicated data rather than the same ordinary object instance, unless a supported resource is transferred.

Common structuredClone() Mistakes

  • Assuming the clone keeps custom class methods and prototypes.
  • Including a function anywhere inside a large object graph.
  • Transferring a buffer and then trying to reuse the detached original.
  • Using JSON conversion when Date, Map, Set, typed arrays, or cycles matter.
  • Cloning large state repeatedly when a smaller targeted copy is sufficient.

Conclusion

JavaScript structuredClone() provides reliable deep copying for supported data, including cycles and many built-in types. Use it when the clone must be independent, transfer large resources only when ownership should move, catch DataCloneError for uncertain input, and reconstruct class behavior explicitly when plain copied data is not enough.



Found This Page Useful? Share It!
Get the Latest Tutorials and Updates
Join us on Telegram