DEV Community

DevFrontier
DevFrontier

Posted on

Everything You Need to Know About JSON.parse() and JSON.stringify()

Working with JSON (JavaScript Object Notation) is a fundamental skill for any JavaScript developer. Whether you're fetching data from an API, storing state in localStorage, or communicating between services, two methods play a central role:

  • JSON.parse() – converts JSON strings into JavaScript objects.
  • JSON.stringify() – converts JavaScript objects into JSON strings.

In this article, we’ll cover how they work, their options, pitfalls, and advanced use cases.

What is JSON?

JSON (JavaScript Object Notation) is a lightweight data format used to represent structured data. It’s human-readable and language-independent, making it the most common format for APIs and data storage.

A JSON string looks like this:

{
  "name": "Alice",
  "age": 25,
  "isAdmin": false,
  "skills": ["JavaScript", "React", "Node.js"]
}
Enter fullscreen mode Exit fullscreen mode

But in JavaScript, this would be represented as an object:

{
  name: "Alice",
  age: 25,
  isAdmin: false,
  skills: ["JavaScript", "React", "Node.js"]
}
Enter fullscreen mode Exit fullscreen mode

JSON.parse()

Basic Usage

JSON.parse() takes a JSON string and converts it into a JavaScript object:

const jsonString = '{"name":"Alice","age":25}';
const obj = JSON.parse(jsonString);

console.log(obj.name); // "Alice"
console.log(obj.age);  // 25
Enter fullscreen mode Exit fullscreen mode

With Arrays

const jsonArray = '[1, 2, 3, 4]';
const arr = JSON.parse(jsonArray);

console.log(arr[0]); // 1
Enter fullscreen mode Exit fullscreen mode

Error Handling
If the string is not valid JSON, it throws a SyntaxError:

try {
  JSON.parse("{name: 'Alice'}"); // Invalid JSON
} catch (e) {
  console.error("Parsing failed:", e.message);
}

Enter fullscreen mode Exit fullscreen mode

Tip: Always wrap JSON.parse() in try...catch when working with external data.

The reviver Function

JSON.parse() can take a second argument — a reviver function — to transform values while parsing:

const data = '{"name":"Alice","birthYear":1995}';

const obj = JSON.parse(data, (key, value) => {
  if (key === "birthYear") {
    return new Date().getFullYear() - value; // Convert to age
  }
  return value;
});

console.log(obj); // { name: "Alice", birthYear: 30 } (assuming current year = 2025)
Enter fullscreen mode Exit fullscreen mode

JSON.stringify()

Basic Usage

**JSON.stringify() **converts an object into a JSON string:

const obj = { name: "Alice", age: 25 };
const jsonString = JSON.stringify(obj);

console.log(jsonString);
// '{"name":"Alice","age":25}'
Enter fullscreen mode Exit fullscreen mode

With Arrays

const arr = [1, 2, 3];
console.log(JSON.stringify(arr)); // "[1,2,3]"
Enter fullscreen mode Exit fullscreen mode

Handling Non-Serializable Values

  • undefined, functions, and symbols are skipped:
const obj = { a: 1, b: undefined, c: () => {} };
console.log(JSON.stringify(obj)); // '{"a":1}'
Enter fullscreen mode Exit fullscreen mode
  • NaN, Infinity, and -Infinity become null:
console.log(JSON.stringify([NaN, Infinity, -Infinity])); // "[null,null,null]"
Enter fullscreen mode Exit fullscreen mode

The replacer Function

You can control what gets included using a replacer function or array:

const user = { name: "Alice", age: 25, password: "secret" };

// Function replacer
console.log(JSON.stringify(user, (key, value) => {
  if (key === "password") return undefined;
  return value;
}));
// '{"name":"Alice","age":25}'

// Array replacer (whitelist keys)
console.log(JSON.stringify(user, ["name", "age"]));
// '{"name":"Alice","age":25}'

Enter fullscreen mode Exit fullscreen mode

Pretty Printing (Indentation)
You can add spacing to make JSON more readable:

const obj = { name: "Alice", age: 25 };
console.log(JSON.stringify(obj, null, 2));
Enter fullscreen mode Exit fullscreen mode

Output:

{
  "name": "Alice",
  "age": 25
}
Enter fullscreen mode Exit fullscreen mode

Common Use Cases

Local Storage

localStorage only stores strings, so JSON.stringify() and JSON.parse() are essential:

const user = { name: "Alice", age: 25 };

// Save
localStorage.setItem("user", JSON.stringify(user));

// Retrieve
const savedUser = JSON.parse(localStorage.getItem("user"));
console.log(savedUser.name); // "Alice"
Enter fullscreen mode Exit fullscreen mode

API Requests & Responses

Most APIs send and receive JSON:

fetch("/api/user")
  .then(res => res.json()) // equivalent to JSON.parse()
  .then(data => console.log(data));
Enter fullscreen mode Exit fullscreen mode

When sending data:

fetch("/api/user", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: "Alice", age: 25 })
});
Enter fullscreen mode Exit fullscreen mode

Deep Cloning Objects

A common trick is to deep-clone an object with JSON:

const obj = { name: "Alice", skills: ["JS"] };
const clone = JSON.parse(JSON.stringify(obj));

clone.skills.push("React");

console.log(obj.skills);   // ["JS"]
console.log(clone.skills); // ["JS", "React"]
Enter fullscreen mode Exit fullscreen mode

⚠️ Caveat: This fails with functions, Dates, Map, Set, and other non-JSON values.

Pitfalls & Limitations

Circular References
Objects with self-references cannot be stringified:

const obj = {};
obj.self = obj;
JSON.stringify(obj); // Throws TypeError
Enter fullscreen mode Exit fullscreen mode

Loss of Data Types

  • Dates become strings
  • undefined, functions, symbols are removed
  • Map, Set, RegExp are not preserved

Performance Concerns
For very large objects, JSON.stringify() and JSON.parse() can be slow. Libraries like flatted or superjson help handle advanced cases.

. Alternatives & Advanced Tools

structuredClone() – modern alternative for deep cloning, supports more types than JSON.parse(JSON.stringify(...)).

Libraries:

  • superjson
    for preserving Dates, Maps, Sets.

  • flatted
    for circular structures.

Quick Reference


Conclusion

JSON.parse() and JSON.stringify() are deceptively simple but incredibly powerful. They’re essential for:

  • Converting between strings and objects
  • Safely storing and transmitting data
  • Controlling serialization with replacer/reviver
  • Debugging with pretty-printing

By mastering these two methods, you’ll unlock smoother workflows with APIs, storage, and data manipulation in JavaScript.

Top comments (0)