NV ToolkitFormat · Validate · Convert
Guide

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.

By NaveenKumar T · Software engineer · builds and maintains NV Toolkit Published 2026-06-04 2 min read

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.

javascript
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.

javascript
// 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.

How this was tested: The JavaScript examples were run with Node 22 on 2026-09-10.

Sources

  1. MDN — JSON.stringify()
  2. MDN — console.table() static method
  3. RFC 8259 — The JSON Data Interchange Format

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 & share

Keep working

Related tools