Pretty Print JSON in JavaScript: stringify and Beyond
JSON.stringify hides its best feature in the third argument. Two characters — , 2 — turn compact output into readable output. Here's the full API, the console shortcuts, and the two errors everyone eventually hits.
In short
Pretty print JSON in JavaScript by passing a number of spaces (or a string like '\t') as the third argument to JSON.stringify(value, replacer, space) — the second argument, replacer, can whitelist keys or transform values on the way out, such as redacting secrets. For debugging without a string, console.dir and console.table beat stringify; watch for circular-reference TypeErrors and silently dropped undefined values.
The third argument is the whole trick
JSON.stringify(value, replacer, space): pass a number (spaces per level, max 10) or a string (used literally — '\t' for tabs) as space. The forgotten middle argument, replacer, filters or transforms: an array whitelists keys; a function rewrites values on the way out — the idiomatic way to drop secrets from logged payloads.
const user = { id: 7, name: "Ada", token: "secret-123" };
JSON.stringify(user, null, 2); // pretty, everything
JSON.stringify(user, ["id", "name"], 2); // whitelist: drops token
JSON.stringify(user, (k, v) => k === "token" ? "[redacted]" : v, 2);
// Re-format an existing JSON string:
JSON.stringify(JSON.parse(raw), null, 2);Console moves that beat stringify
While debugging, you often don't need a string at all: console.dir(obj, { depth: null }) prints the live object with full depth in Node; browser consoles render objects interactively by default. console.table(arrayOfObjects) turns record lists into an actual table — frequently the most readable view of API data there is. Reach for stringify when the output must travel: logs, files, tickets, network.
The two classic errors
TypeError: Converting circular structure to JSON — your object graph loops (DOM nodes, ORM entities, this in classes). Fix with a replacer that tracks seen objects, or structuredClone first if the cycle is incidental. And the silent one: undefined, functions, and symbols vanish from objects (and become null in arrays) — not an error, just a surprise when keys you expected are missing downstream. Dates serialize as ISO strings, not Date objects, by design. If you're unsure whether the resulting string is valid JSON, a quick pass through our JSON Validator settles it.
// Circular-safe replacer
const seen = new WeakSet();
JSON.stringify(obj, (k, v) => {
if (typeof v === "object" && v !== null) {
if (seen.has(v)) return "[circular]";
seen.add(v);
}
return v;
}, 2);Showing pretty JSON on a page
Wrap output in <pre> (or set white-space: pre) — without it, HTML collapses your hard-won line breaks back into one line. Escape < and & before injecting into innerHTML, or just use textContent which needs no escaping. For anything fancier — syntax colors, folding, search — embedding a real editor view is the production answer; for quick sharing, paste into our formatter and send the link.
Sources
Frequently asked questions
JSON.stringify(obj, null, 2) — why the null?
It's the replacer slot, and null means 'no filtering, keep everything'. You're skipping argument two to reach argument three (the indentation). Passing 2 as the second argument would silently whitelist nothing and output undefined-ish results.
How do I pretty print with tabs instead of spaces?
Pass the string instead of a number: JSON.stringify(obj, null, '\t'). Any string up to 10 characters works as the indent unit — though anything beyond tabs or spaces produces output only you will love.
Why did my object's methods disappear in the output?
JSON has no function type, so stringify drops them silently (in objects) — same for undefined and symbols. JSON serializes data, not behavior; if a value must survive, make it a string or restructure.
Need the formatted result outside your code? Paste it into the JSON Formatter — validate, explore as a tree, and download or share in one place.
Format & shareKeep working
Related tools
JSON Formatter
Format, beautify, and validate JSON instantly in a professional VS Code-style editor — free, fast, and 100% private.
JavaScript Formatter
The formatter your CI runs, in a browser tab — prettier-consistent JavaScript in one click.
JSON Stringify Online
The exact behavior of JavaScript's JSON.stringify() — compact by default, the space argument, and what the serializer silently drops — plus a mode that reverses it.
JSON Parser
Run a real JSON parse in your browser — see exactly what your application will see, or exactly where it will fail.
JSBeautifier
The classic js-beautify engine — the fastest way to make minified JavaScript readable again.
TypeScript Formatter
Prettier for TypeScript — generics, decorators and annotations formatted the way your repo expects.
Babel Formatter
Prettier's Babel parser — the most syntax-tolerant way to format modern and experimental JavaScript.
Flow Formatter
Prettier with the Flow parser — annotations and Flow-specific syntax formatted without a fight.
JavaScript Escape
Make any text safe inside a JavaScript string literal — quotes, backslashes, newlines and control characters handled both ways.
JSON to String
Turn a JSON document into a complete, ready-to-paste string literal for the language you're actually writing — quotes and delimiters included, not just an escaped body.