Skip to content
AldeaCode Logo
JSON Formatter / JavaScript Format 100% local

Format JSON in JavaScript: JSON.stringify done right

Every JS dev has typed `JSON.stringify(obj)` and shipped a single-line wall of text into a log. The third argument exists, the replacer is underused, and BigInt will silently throw at runtime.

The third argument is what you want

JSON.stringify(value, replacer, space) takes a third argument that everyone forgets. Pass 2 and you get pretty output. Pass a string and that string becomes the indent literal. Pass nothing and you get the wall of text.

For console debugging the canonical move is console.log(JSON.stringify(obj, null, 2)). For logs that a backend will index later, drop the indent and use a structured logger instead.

The replacer is not just a curiosity

The second argument can be a function that filters or transforms each key-value pair before it is serialised. Two real uses:

Hide secrets without mutating the object: ``js const safe = JSON.stringify(user, (k, v) => k === "password" || k === "token" ? "[REDACTED]" : v, 2); ``

Pass an array of keys to whitelist only those properties. Useful when you receive an object with 30 fields and want to log only 3.

The BigInt and circular reference traps

JSON.stringify does not know how to serialise BigInt and will throw TypeError: Do not know how to serialize a BigInt. Convert to string before stringifying: v => typeof v === "bigint" ? v.toString() : v inside the replacer.

Circular references throw Converting circular structure to JSON. Either use util.inspect in Node, or maintain a Set of seen values inside the replacer to break the cycle.

localStorage truncation is silent

Browsers cap localStorage at around 5 MB. JSON.stringify of a deeply nested object can blow past that without warning. Wrap your write in a try/catch on QuotaExceededError and surface the failure rather than letting state silently drift.

Working example

javascript
const user = {
  id: 42,
  name: "Ada",
  password: "p@ssw0rd",
  tags: ["admin", "beta"],
  bigField: 9007199254740993n, // BigInt
};

const formatted = JSON.stringify(
  user,
  (key, value) => {
    if (key === "password") return "[REDACTED]";
    if (typeof value === "bigint") return value.toString();
    return value;
  },
  2,
);

console.log(formatted);

Just need the result?

When you just need to format a blob you grabbed from a network tab, the browser-based formatter is one paste away. It validates as it formats, surfaces the exact line of any syntax error, and never sends your payload anywhere.

Open JSON Formatter and Validator →

Frequently asked questions

Does JSON.stringify preserve property order?

Yes for string keys (insertion order). Numeric-like string keys are sorted ascending first. If determinism matters for diffs, pass an explicit array as the replacer to fix the order.

How do I parse and re-stringify in one step to canonicalise?

JSON.stringify(JSON.parse(input), null, 2). Round-tripping through parse normalises whitespace, key order quirks, and trailing commas (which would have failed parse anyway).

Is the global JSON object available in every JS runtime?

Yes. JSON is part of ES5 (2009) and is available in every Node version since 0.x, every browser since IE8, and every embedded JS runtime worth using.