JSON.stringify() has a built-in way to produce formatted, indented output — most developers just never use the third argument. This guide covers pretty-printing JSON in JavaScript, plus the lesser-known replacer and key-sorting tricks.

The indent argument

The third parameter of JSON.stringify(value, replacer, space) controls indentation:

const data = { name: "Alice", roles: ["admin"] };

JSON.stringify(data);
// {"name":"Alice","roles":["admin"]}

JSON.stringify(data, null, 2);
// {
//   "name": "Alice",
//   "roles": [
//     "admin"
//   ]
// }

Two spaces is the most common choice. Use a string like "\t" for tab indentation.

The replacer argument

The second argument filters or transforms values. Pass an array of keys to keep only those:

JSON.stringify(user, ["id", "name"], 2);

Or a function to transform each value:

JSON.stringify(data, (key, value) =>
  typeof value === "string" ? value.toUpperCase() : value
, 2);

Sorting keys alphabetically

function sortedStringify(obj) {
  const keys = new Set();
  JSON.stringify(obj, (k, v) => (keys.add(k), v));
  return JSON.stringify(obj, Array.from(keys).sort(), 2);
}

Format JSON without writing code

Paste your JSON and get it beautifully indented instantly — plus sort keys, minify, and validate. Free and private.

Open tool →

Handling circular references

Self-referencing objects throw TypeError: Converting circular structure to JSON. Track seen objects:

function safeStringify(obj) {
  const seen = new WeakSet();
  return JSON.stringify(obj, (k, v) => {
    if (typeof v === "object" && v !== null) {
      if (seen.has(v)) return "[Circular]";
      seen.add(v);
    }
    return v;
  }, 2);
}

Common gotchas

  • undefined, functions, and symbols are omitted from objects and become null in arrays.
  • Date objects serialize to ISO strings.
  • BigInt throws — convert to a string first.
  • Minify (no spacing argument) before sending over the network.