How to Pretty-Print JSON: Terminal, Editor & Browser
The commands that pretty-print JSON in one step — jq, python -m json.tool, node, prettier and editor shortcuts — plus how to minify or sort keys.
Paste it into the formatter, or pick a command — the fastest route depends on where the JSON lives. In a terminal it’s jq .; in Python it’s python3 -m json.tool; in VS Code it’s Format Document. Every option below handles standard JSON; the last FAQ answer covers what parsing and re-printing can change.
The commands, by environment
| Where | Command | Output notes |
|---|---|---|
| Any shell, jq installed | jq . file.json or curl -s URL | jq . |
2-space indent, key order preserved |
| Validate only | jq empty file.json |
silent on success, error + position on failure |
| Python (no install needed) | python3 -m json.tool file.json |
4-space indent, escapes non-ASCII by default |
| Python, keep Unicode | python3 -m json.tool --no-ensure-ascii f.json |
real UTF-8 output |
| Node | node -e "console.log(JSON.stringify(JSON.parse(require('fs').readFileSync('f.json','utf8')),null,2))" |
2-space, re-serializes numbers |
| Prettier | npx prettier --write f.json |
formats in place, project-style indent |
| VS Code | open file → Shift+Alt+F (macOS ⇧⌥F) | Format Document on .json |
| Browser console | JSON.stringify(obj, null, 2) |
2-space string you can copy |
Worked example
$ echo '{"user":"ada","roles":["admin","dev"],"active":true}' | jq .
{
"user": "ada",
"roles": [
"admin",
"dev"
],
"active": true
}
The three moves people actually want
Minify (the reverse): jq -c . file.json, or python3 -m json.tool --compact. One line, no whitespace — what you want for .env-style transport or a single-cell config field.
Sort keys: jq -S . sorts recursively; --sort-keys does the same in json.tool. Handy for diffing two config files where key order is noise. The formatter has a Sort keys toggle that does the same recursively in the browser (apart from whole-number keys, which always come first in numeric order) — useful when the JSON shouldn’t leave the machine.
Find the error, not just “invalid”: every CLI above tells you a position when parsing fails, but for a 200 KB payload the formatter’s error panel — exact line, column and a caret under the offending character — is usually faster than binary-searching a file. The companion piece on the 12 common JSON syntax errors shows what each error message actually means; JSON vs JSON5 explains why a config file with comments isn’t valid JSON in the first place.
Frequently asked questions
What's the fastest way to pretty-print JSON in a terminal?
jq . file.json — or pipe it: curl -s URL | jq .. It prints with 2-space indent and keeps key order. No jq? python3 -m json.tool file.json is installed almost everywhere (4-space indent by default; --indent 2 or --tab to change it).
How do I minify (un-pretty-print) JSON on the command line?
jq -c . file.json outputs the whole document on one line. The Python equivalent is python3 -m json.tool --compact file.json. Both parse the data and print it again rather than just deleting spaces, so duplicate keys collapse to the last value and some numbers are re-spelled (jq 1.7 prints 1E5 as 1E+5; Python prints it as 100000.0, and 1e400 as Infinity, which isn't valid JSON).
How do I validate JSON — not just format it?
jq empty file.json prints nothing on success and a line/column error on failure. python3 -m json.tool file.json doubles as a validator — it exits non-zero with a position on bad input. In the browser, paste it into the formatter to get the exact error line, column and a jump-to-error button.
Why does python -m json.tool escape my non-ASCII text?
It defaults to ensure_ascii, so é becomes \u00e9 — valid, but ugly. Pass --no-ensure-ascii to keep real UTF-8 characters in the output. jq keeps them natively.
How do I sort all the keys alphabetically?
jq -S . file.json sorts object keys recursively (array order is untouched). In Python it's python3 -m json.tool --sort-keys file.json. Or use the formatter's Sort keys toggle — it sorts keys at every depth too, except that whole-number keys such as "2" and "10" always come first, in numeric order (jq and Python put "10" before "2").
Does pretty-printing change the data?
Depends on the tool. This site's formatter parses your JSON and prints it back with JSON.stringify, so it is not a whitespace-only rewrite — and neither are jq, Python or Node. Ordinary data comes out with the same values, just re-indented; in this formatter (as in Node) these cases don't: integers beyond ±9,007,199,254,740,991 can lose digits (12345678901234567890 → 12345678901234567000), so keep big IDs as strings; numbers past the 64-bit float range become null (1e400); numbers are re-spelled (1.0 → 1, 1E5 → 100000); whole-number keys ("2", "10"; no leading zeros, up to 4,294,967,294) move to the front in numeric order; and duplicate keys collapse to the last value — RFC 8259 says names should be unique, so fix the source. If you need every token kept as written, use a whitespace-only formatter such as VS Code's built-in Format Document — and check signatures and checksums against the original bytes, never a formatted copy.