JSON.stringify() and JSON.parse() are two of the most-used functions in JavaScript. Most developers use them at their most basic level — but they have powerful options that solve real problems.
JSON.stringify() basics
const data = { name: "Alice", age: 28, active: true };
JSON.stringify(data)
// '{"name":"Alice","age":28,"active":true}'
JSON.stringify(data, null, 2) // pretty-print with 2-space indent
// '{
// "name": "Alice",
// "age": 28,
// "active": true
// }'
JSON.stringify(data, null, ' ') // tab indent
The replacer parameter
The second argument to JSON.stringify() is a replacer — it filters or transforms properties:
const user = { name: "Alice", password: "secret123", age: 28 };
// Array replacer — only include these keys
JSON.stringify(user, ['name', 'age'])
// '{"name":"Alice","age":28}' — password excluded
// Function replacer — full control over each value
JSON.stringify(user, (key, value) => {
if (key === 'password') return undefined; // exclude
if (typeof value === 'number') return value * 2; // transform
return value;
})
// '{"name":"Alice","age":56}'
JSON.parse() basics
const json = '{"name":"Alice","age":28}';
const data = JSON.parse(json);
console.log(data.name); // "Alice"
console.log(typeof data.age); // "number"
// Always use try/catch
try {
const data = JSON.parse(untrustedInput);
} catch (error) {
console.error('Invalid JSON:', error.message);
}
The reviver parameter
JSON.parse() accepts a reviver function to transform values as they're parsed:
const json = '{"name":"Alice","createdAt":"2023-11-14T22:13:20Z","score":"95"}';
const data = JSON.parse(json, (key, value) => {
// Convert date strings to Date objects
if (key === 'createdAt') return new Date(value);
// Convert numeric strings to numbers
if (key === 'score') return Number(value);
return value;
});
console.log(data.createdAt instanceof Date); // true
console.log(typeof data.score); // "number"
What JSON.stringify() ignores
const obj = {
name: "Alice",
fn: function() {}, // functions → undefined (excluded)
sym: Symbol('id'), // symbols → undefined (excluded)
undef: undefined, // undefined values → excluded
inf: Infinity, // Infinity → null
nan: NaN, // NaN → null
date: new Date(), // Date → ISO string
regex: /abc/, // RegExp → {} (empty object!)
};
JSON.stringify(obj)
// '{"name":"Alice","inf":null,"nan":null,"date":"2023-11-14T...","regex":{}}'
Handle circular references
// This throws: "TypeError: Converting circular structure to JSON"
const obj = { name: "Alice" };
obj.self = obj; // circular reference
JSON.stringify(obj); // throws!
// Fix 1: Use a replacer to skip circular refs
function safeStringify(obj) {
const seen = new WeakSet();
return JSON.stringify(obj, (key, value) => {
if (typeof value === 'object' && value !== null) {
if (seen.has(value)) return '[Circular]';
seen.add(value);
}
return value;
});
}
// Fix 2: Use structuredClone() first to detect issues
const clone = structuredClone(obj); // throws on circular refs with clear error
Deep clone with JSON
// Quick deep clone (most common pattern)
const clone = JSON.parse(JSON.stringify(original));
// Limitations:
// - Loses Date objects (becomes strings)
// - Loses undefined values
// - Loses functions
// - Fails on circular references
// Better: use structuredClone() (modern browsers)
const clone = structuredClone(original); // handles more types, no JSON roundtrip
Try it free — JSON Formatter
Validate and format your JSON output from stringify instantly.