JSON.stringify() has three parameters, but most developers only use the first one. The second and third parameters — replacer and space — unlock powerful control over what gets serialized and how it's formatted.
JSON.stringify(value, replacer, space)
The space parameter — controlling indentation
The third argument, space, controls the indentation of the formatted output. It accepts either a number or a string:
Number — spaces per indent level
const data = { name: "Alice", address: { city: "London", zip: "SW1A" } };
// No indent (minified) — default when space is 0, null, or omitted
JSON.stringify(data);
// {"name":"Alice","address":{"city":"London","zip":"SW1A"}}
// 2-space indent
JSON.stringify(data, null, 2);
// {
// "name": "Alice",
// "address": {
// "city": "London",
// "zip": "SW1A"
// }
// }
// 4-space indent
JSON.stringify(data, null, 4);
// {
// "name": "Alice",
// "address": {
// "city": "London",
// "zip": "SW1A"
// }
// }
Values larger than 10 are clamped to 10. Negative values are treated as 0 (minified output).
String — custom indent character
// Tab indentation (useful for some file formats)
JSON.stringify(data, null, '\t');
// {
// <tab>"name": "Alice",
// <tab>"address": {
// <tab><tab>"city": "London",
// <tab><tab>"zip": "SW1A"
// <tab>}
// }
// Custom string (first 10 chars only, per spec)
JSON.stringify(data, null, '--');
// {
// --"name": "Alice",
// --"address": {
// ----"city": "London",
// ----"zip": "SW1A"
// --}
// }
The replacer parameter — filtering and transforming output
The second argument controls which keys appear in the output and what their values are. It can be an array (allowlist) or a function (transformation).
Replacer as an array — include only specific keys
const user = {
id: 42,
name: "Alice",
email: "alice@example.com",
password: "secret123",
createdAt: "2026-05-04"
};
// Only include id and name in the output
JSON.stringify(user, ['id', 'name'], 2);
// {
// "id": 42,
// "name": "Alice"
// }
Replacer as a function — exclude or transform values
// Exclude sensitive fields
JSON.stringify(user, (key, value) => {
if (key === 'password') return undefined; // omit this key
return value; // include everything else
}, 2);
// Exclude multiple sensitive fields
const sensitiveKeys = new Set(['password', 'ssn', 'creditCard']);
JSON.stringify(user, (key, value) => {
return sensitiveKeys.has(key) ? undefined : value;
}, 2);
// Transform values — convert Date objects to ISO strings
const event = {
title: "Conference",
date: new Date('2026-06-15'),
attendees: 250
};
JSON.stringify(event, (key, value) => {
if (value instanceof Date) return value.toISOString();
return value;
}, 2);
// {
// "title": "Conference",
// "date": "2026-06-15T00:00:00.000Z",
// "attendees": 250
// }
Important: how the replacer function is called
The replacer function is called with the key and value for every key-value pair, including the root object. For the root, the key is an empty string "". If the replacer returns undefined for any key, that key is omitted from the output. If it returns undefined for the root (empty key), the entire output is undefined.
JSON.stringify({ a: 1, b: 2 }, (key, value) => {
console.log(JSON.stringify(key), '→', value);
return value;
});
// "" → { a: 1, b: 2 } (root call, key is empty string)
// "a" → 1
// "b" → 2
toJSON() — custom serialization on objects
If an object has a toJSON() method, JSON.stringify() calls it and serializes the returned value instead of the object itself:
class User {
constructor(id, name, password) {
this.id = id;
this.name = name;
this.password = password;
}
// This controls what JSON.stringify serializes
toJSON() {
return { id: this.id, name: this.name }; // omit password
}
}
const user = new User(1, 'Alice', 'secret');
JSON.stringify(user); // '{"id":1,"name":"Alice"}'
Browser alternative for one-off formatting
If you need to format a JSON string without writing code, paste it into the JSON Formatter. It supports 2-space and 4-space indentation, a tree view for navigation, and key sorting — equivalent to JSON.stringify(data, null, 2) with the sort-keys option.