DEV Community

Cover image for structuredClone() vs JSON.stringify(): Which One Should You Use?
Ayman Eldawy
Ayman Eldawy

Posted on Originally published at lnkd.in

structuredClone() vs JSON.stringify(): Which One Should You Use?

Before using JSON.stringify() to deep-copy an object, there's something you should know.

One of the common tricks for creating a deep copy in JavaScript has always been:

const copy = JSON.parse(JSON.stringify(object));
Enter fullscreen mode Exit fullscreen mode

It works.

Until your object contains something JSON wasn't designed to handle.

So let's compare:

structuredClone() vs JSON.stringify() for deep copying.

Let's take it one step at a time.

The old trick: JSON.stringify() + JSON.parse()

The idea is simple.

First, convert the object into a JSON string:

JSON.stringify(object)
Enter fullscreen mode Exit fullscreen mode

Then convert it back into a new object:

JSON.parse(...)
Enter fullscreen mode Exit fullscreen mode

You now have a new object with no nested references shared with the original.

The problem?

JSON.stringify() wasn't designed for cloning objects.

It was designed for JSON serialization.

And that difference matters.

For example:

const user = {
  name: "Ayman",
  createdAt: new Date(),
  value: undefined,
};

const copy = JSON.parse(JSON.stringify(user));
Enter fullscreen mode Exit fullscreen mode

After cloning:

  • Date becomes a string.
  • undefined properties disappear.
  • Functions inside objects disappear.
  • Map and Set don't preserve their contents normally.
  • BigInt can throw an error.

And circular references?

const user = {
  name: "Ayman"
};

user.self = user;

JSON.stringify(user);
Enter fullscreen mode Exit fullscreen mode

That throws a TypeError.

JSON simply doesn't have a way to represent that circular reference.

Then we got structuredClone()

Instead of converting the object to a string and parsing it again:

const copy = structuredClone(object);
Enter fullscreen mode Exit fullscreen mode

That's it.

structuredClone() was actually designed for cloning structured data.

It supports many types that the JSON trick doesn't preserve correctly:

  • Date
  • RegExp
  • Map
  • Set
  • ArrayBuffer
  • Typed Arrays
  • Blob
  • File

And remember our circular reference?

const user = {
  name: "Ayman"
};

user.self = user;

const copy = structuredClone(user);

console.log(copy.self === copy);
// true
Enter fullscreen mode Exit fullscreen mode

No problem.

The relationship between the references is preserved in the cloned object.

But structuredClone() isn't magic either.

Functions still can't be cloned:

structuredClone({
  sayHello() {}
});

// DataCloneError
Enter fullscreen mode Exit fullscreen mode

DOM nodes can't be cloned with it either, and things like property descriptors, getters/setters, prototype chains, and RegExp.lastIndex aren't necessarily preserved.

So it's a much better general-purpose cloning tool.

But it's not a universal "clone literally anything" button.

So which one should you use?

If your actual goal is:

"I need an independent deep copy of this data."

structuredClone() is usually the better tool.

const copy = structuredClone(original);
Enter fullscreen mode Exit fullscreen mode

Especially when your data contains things like Date, Map, Set, or circular references.

But if your goal is actually serialization:

const json = JSON.stringify(data);
Enter fullscreen mode Exit fullscreen mode

Then use JSON.stringify().

For example, when you need JSON to send through an API, store as text, or work with a system that expects JSON.

And yes, the old:

JSON.parse(JSON.stringify(object))
Enter fullscreen mode Exit fullscreen mode

still works for simple JSON-compatible data.

Just remember what you're actually doing.

You're not using a cloning API.

You're serializing the object... then rebuilding it.


This is the third post in Frontend Battles series, where I'll compare popular frontend tools, libraries, and technologies to help you understand their strengths, trade-offs, and when to choose each one.

Top comments (1)