JSON.stringify() vs JSON.parse() — Complete Difference Guide

JSON.stringify() and JSON.parse() are the two most important JSON methods in JavaScript. One converts objects to strings; the other converts strings back to objects. Understanding both — including their edge cases and gotchas — is essential for every developer working with APIs, localStorage, or any data exchange.

Object→String

JSON.stringify() direction

String→Object

JSON.parse() direction

Serialization

what stringify is called

Deserialization

what parse is called

1

The Core Difference

These two methods are inverse operations. JSON.stringify() converts a JavaScript value (object, array, primitive) into a JSON-formatted string. JSON.parse() takes a JSON string and converts it back into a JavaScript value. They form a complete serialization cycle.

Quick fact

JSON stands for JavaScript Object Notation. Despite the name, JSON is a language-independent format used across Python, Java, Ruby, Go, and virtually every other programming language.

2

JSON.stringify() — Object to String

Use JSON.stringify() whenever you need to convert a JavaScript value into a string for transmission or storage: sending to an API, saving in localStorage, writing to a file, or logging objects as readable text.

javascriptJSON.stringify() Basic Usage
const user = { name: "Alice", age: 30, active: true };

// Basic stringify
const json = JSON.stringify(user);
console.log(json);
// → '{"name":"Alice","age":30,"active":true}'
console.log(typeof json);
// → 'string'

// With indentation (pretty print)
const pretty = JSON.stringify(user, null, 2);
console.log(pretty);
// → {
//     "name": "Alice",
//     "age": 30,
//     "active": true
//   }

// Arrays work too
const items = [1, "hello", true, null];
console.log(JSON.stringify(items));
// → '[1,"hello",true,null]'

The replacer parameter

JSON.stringify() accepts a second argument — a replacer — that lets you filter or transform which properties get included. Pass an array of strings to include only specific keys, or a function for custom logic.
javascriptJSON.stringify() Advanced — Replacer and Indentation
const data = {
  id: 1,
  name: "Alice",
  password: "secret123",  // we want to exclude this
  createdAt: new Date("2024-01-01"),
};

// Array replacer: only include these keys
const safe = JSON.stringify(data, ["id", "name"]);
console.log(safe);
// → '{"id":1,"name":"Alice"}'

// Function replacer: custom logic
const result = JSON.stringify(data, (key, value) => {
  if (key === "password") return undefined;  // exclude
  if (value instanceof Date) return value.toISOString(); // transform
  return value;
});
console.log(result);
// → '{"id":1,"name":"Alice","createdAt":"2024-01-01T00:00:00.000Z"}'

// Third argument: indentation (2 or 4 spaces, or a string like "	")
console.log(JSON.stringify({ a: 1 }, null, 4));
// → {
//       "a": 1
//   }
3

JSON.parse() — String to Object

Use JSON.parse() whenever you receive a JSON string and need to work with it as a JavaScript value: reading from an API response, loading from localStorage, or parsing JSON files.

javascriptJSON.parse() Basic Usage
const jsonString = '{"name":"Bob","age":25,"tags":["js","react"]}';

// Basic parse
const obj = JSON.parse(jsonString);
console.log(obj.name);    // → 'Bob'
console.log(obj.tags[0]); // → 'js'
console.log(typeof obj);  // → 'object'

// Parse numbers and booleans
const config = JSON.parse('{"debug":true,"maxRetries":3,"timeout":5000}');
console.log(config.debug);      // → true  (boolean, not string)
console.log(config.maxRetries); // → 3     (number, not string)

// Parse arrays
const ids = JSON.parse('[1, 2, 3, 4, 5]');
console.log(ids.length); // → 5
javascriptJSON.parse() with Reviver Function
// The reviver runs on every parsed key-value pair
const json = '{"name":"Alice","createdAt":"2024-01-15T10:30:00.000Z","score":95}';

const data = JSON.parse(json, (key, value) => {
  // Convert date strings back to Date objects
  if (key === "createdAt") return new Date(value);
  return value;
});

console.log(data.createdAt instanceof Date); // → true
console.log(data.createdAt.getFullYear());   // → 2024
4

Error Handling — Never Skip Try-Catch

JSON.parse() throws a SyntaxError if the string is not valid JSON. In production code, always wrap it in a try-catch. JSON.stringify() can also throw for circular references.

❌ Bad
// No error handling — crashes on invalid JSON
function loadConfig(jsonStr) {
  return JSON.parse(jsonStr); // throws SyntaxError if invalid
}

// Calling with malformed JSON
loadConfig("{broken json,}"); // Uncaught SyntaxError!
✅ Good
// Always wrap JSON.parse in try-catch
function safeParseJSON(jsonStr, fallback = null) {
  try {
    return JSON.parse(jsonStr);
  } catch (error) {
    console.error('JSON parse failed:', error.message);
    return fallback;
  }
}

// Safe — returns null instead of throwing
const result = safeParseJSON("{broken}", null);
console.log(result); // → null
javascriptHandling Circular Reference in JSON.stringify()
// Circular reference causes TypeError
const obj = { name: "Alice" };
obj.self = obj;  // circular!

// This throws: TypeError: Converting circular structure to JSON
// JSON.stringify(obj);

// Solution 1: Remove circular references before stringify
const { self, ...safeObj } = obj;
console.log(JSON.stringify(safeObj)); // → '{"name":"Alice"}'

// Solution 2: Use a library like flatted or json-stringify-safe
// import { stringify } from 'flatted';
// console.log(stringify(obj)); // handles circular refs
5

What Gets Lost in Stringify

JSON only supports a subset of JavaScript types. Several things are silently dropped or transformed when you stringify an object. This is a very common source of bugs.

Types lost during JSON.stringify()

undefined values (property is omitted), functions (omitted), Symbols (omitted), Date objects (converted to ISO string — not restored on parse), NaN and Infinity (converted to null), and Map/Set objects (converted to empty object).
javascriptValues That Get Lost or Changed
const data = {
  name: "Alice",
  fn: () => "hello",         // function → omitted
  sym: Symbol("id"),         // Symbol → omitted
  undef: undefined,           // undefined → omitted
  date: new Date("2024-01-01"), // Date → ISO string
  nan: NaN,                   // NaN → null
  inf: Infinity,              // Infinity → null
  map: new Map([["a", 1]]),   // Map → {} (empty object!)
  set: new Set([1, 2, 3]),    // Set → {} (empty object!)
};

const json = JSON.stringify(data);
const parsed = JSON.parse(json);

console.log(parsed);
// → {
//     name: "Alice",
//     date: "2024-01-01T00:00:00.000Z",  // string, not Date!
//     nan: null,
//     inf: null,
//     map: {},   // lost all data!
//     set: {},   // lost all data!
//   }
// fn, sym, undef are completely gone!
6

Common Use Cases with Code

javascriptAPI Request with fetch()
// Sending JSON to an API
async function createUser(userData) {
  const response = await fetch('/api/users', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(userData),  // ← stringify for transmission
  });

  if (!response.ok) throw new Error('Request failed');

  const newUser = await response.json(); // ← response.json() calls JSON.parse internally
  return newUser;
}

const user = await createUser({ name: "Carol", email: "carol@example.com" });
javascriptlocalStorage — Persist Objects
// Save object to localStorage
function saveSettings(settings) {
  localStorage.setItem('app-settings', JSON.stringify(settings));
}

// Load object from localStorage
function loadSettings(defaults = {}) {
  const stored = localStorage.getItem('app-settings');
  if (!stored) return defaults;
  try {
    return JSON.parse(stored);
  } catch {
    return defaults;
  }
}

saveSettings({ theme: 'dark', fontSize: 14 });
const settings = loadSettings({ theme: 'light', fontSize: 12 });
console.log(settings.theme); // → 'dark'
javascriptDeep Clone an Object (Simple Objects Only)
// Quick deep clone using stringify + parse
// WARNING: only works for JSON-safe values (no functions, Dates, etc.)
function deepClone(obj) {
  return JSON.parse(JSON.stringify(obj));
}

const original = { user: { name: "Dave", scores: [10, 20, 30] } };
const clone = deepClone(original);

clone.user.name = "Eve";
clone.user.scores.push(40);

console.log(original.user.name);    // → 'Dave' (unchanged)
console.log(original.user.scores);  // → [10, 20, 30] (unchanged)

// For production: use structuredClone() instead (handles Dates, Maps, etc.)
7

Performance Considerations

JSON.stringify is expensive for large objects

For deeply nested or large objects (thousands of keys), stringify can be a bottleneck. Profile before optimizing — usually it's not the bottleneck.

JSON.parse is generally fast

V8 and other engines have heavily optimized JSON.parse. For most use cases, parsing even large JSON strings is very fast.

Avoid parsing the same string multiple times

If you need to read a JSON string multiple times, parse it once and reuse the object. Parsing is idempotent but not free.

Use streaming parsers for huge data

For files or API responses over several MB, use streaming JSON parsers (like node-JSONStream) instead of parsing the entire string at once.

8

Quick Reference

javascriptComplete Cheat Sheet
// ═══════════════════════════════════════════
// JSON.stringify() — JavaScript → JSON string
// ═══════════════════════════════════════════

JSON.stringify(value)              // basic
JSON.stringify(value, null, 2)     // pretty print (2 spaces)
JSON.stringify(value, ["key1"])    // only include these keys
JSON.stringify(value, replacerFn)  // custom transform

// ════════════════════════════════════════════
// JSON.parse() — JSON string → JavaScript value
// ════════════════════════════════════════════

JSON.parse(jsonString)             // basic
JSON.parse(jsonString, reviverFn)  // with type transformation

// ═══════════════════
// ALWAYS use try-catch
// ═══════════════════

try {
  const data = JSON.parse(maybeJson);
} catch (e) {
  // handle invalid JSON
}

// ════════════════════════════════════════════════
// What JSON supports:
// string, number, boolean, null, object, array
//
// What JSON does NOT support:
// undefined, function, Symbol, Date, NaN, Infinity
// Map, Set, BigInt
// ════════════════════════════════════════════════

Frequently Asked Questions

Need to work with JSON data? Try our free JSON Parser and Beautifier and JSON.stringify() online tool.