To pretty-print JSON, run it through any JSON parser and re-serialize it with indentation. The fastest way with data in your clipboard: paste it into the JSON Formatter and press Format — you get 2-space-indented output, validation with exact error positions, and nothing leaves your browser. The same job has one-liners in the terminal and in code, below.
What pretty-printing does
Minified JSON is a single line with no spaces — correct for machines, unreadable for people. Pretty-printing inserts newlines and indentation between tokens so the structure becomes visible. This one-line document:
{"user":{"id":42,"name":"Ada","roles":["admin","dev"]}}becomes:
{
"user": {
"id": 42,
"name": "Ada",
"roles": [
"admin",
"dev"
]
}
}Since whitespace between tokens carries no meaning in JSON (RFC 8259, section 2), the two documents are identical to every parser. The cost is measurable but small at this scale: the minified version is exactly 55 bytes, the 2-space pretty version 100 bytes — an 82% size increase that gzip mostly claws back on the wire. Pretty-printing is lossless and reversible — the reverse operation is minifying.
In the browser (no install)
- Open the JSON Formatter & Validator.
- Paste the JSON, drop a .json file onto the input pane, or use the Upload button.
- Press Format (or Cmd/Ctrl + Enter). Invalid input shows the exact line and column of the first error instead of output.
- Copy the result or download it as a file.
Enable the Sort keys toggle if you also want every object's keys alphabetized — useful before diffing two documents.
In the terminal
jq is the standard: jq . data.json pretty-prints to stdout, and curl -s https://api.example.com/users | jq . formats an API response inline. Without jq, Python is preinstalled almost everywhere: python3 -m json.tool data.json, or Node: node -e "console.log(JSON.stringify(JSON.parse(require('fs').readFileSync(0,'utf8')),null,2))".
In code
Every mainstream language does this natively. JavaScript: JSON.stringify(value, null, 2) — the third argument is the indent. Python: json.dumps(value, indent=2). Go: json.MarshalIndent(v, "", " "). The principle is identical everywhere: parse, then serialize with an indent parameter.
In the browser console
Debugging a live page? You already have a pretty-printer open. With an object in hand, copy(JSON.stringify(obj, null, 2)) in the dev-tools console puts formatted JSON straight on your clipboard. For a response you are about to fetch, await (await fetch(url)).json() renders as an expandable tree in the console — often better than text, because you can collapse the parts you don't care about. And the Network tab's Preview pane pretty-prints every JSON response automatically; the Response tab next to it shows the raw minified bytes.
JSON Lines is a different animal
Log files often contain JSON Lines (also called NDJSON): one complete JSON document per line, newline-separated. A .jsonl file as a whole is not valid JSON — paste one into a formatter and you get an error like Unexpected token { at line 2, because a second document begins where the parser expected the end of input. Pretty-print such files one line at a time, or with jq ., which processes a stream of documents natively. The mirror-image mistake — pretty-printing a document that a log shipper then expects on one line — is why log pipelines want minified JSON.
When you should not pretty-print
Keep JSON minified where machines consume it and bytes count: API responses, embedded data attributes, cache entries. A pretty-printed 10 KB payload is typically 25–35% larger than its minified form. The right habit is: pretty in the repo and the editor, minified on the wire — and a formatter in the middle when you need to cross between the two.
