How to format JSON: pretty print, minify, and sort keys
Format JSON from the command line, in JavaScript, or in the browser. Covers indentation, minifying, sorting keys, and what formatting never changes.
Most JSON you receive from a server is deliberately unreadable: one long line with no spaces, built for machines. Formatting it is the first thing you do when something looks wrong in an API response, a webhook body, or a log entry. This guide shows several ways to format JSON, from a terminal one-liner to a few lines of code, and explains what formatting does and does not change.
What formatting actually changes
Formatting rewrites only the whitespace between tokens. JSON allows spaces, tabs, line feeds, and carriage returns between its structural characters, and parsers ignore them. That means a pretty-printed document and a minified one parse to exactly the same value. Keys, strings, numbers, booleans, and null are untouched, and so is the order of array elements.
Whitespace inside strings is different, because it is part of the value. A good formatter never touches it. Another thing to keep in mind is that formatting is not repair. If the input has a trailing comma or a single-quoted key, a formatter built on a real parser will refuse it, and that refusal is useful information rather than a bug.
Format JSON in JavaScript
If you are already in a browser console or a Node script, JSON.stringify does the job. Its third argument controls indentation: a number gives that many spaces per level, and a string such as a tab character is used as-is. The second argument is a replacer, which you can leave as null.
Parse first, then stringify. This also serves as a quick validity check, since JSON.parse throws a SyntaxError on bad input.
const raw = '{"user":{"id":7,"name":"Nia"},"roles":["reader","editor"]}';
const pretty = JSON.stringify(JSON.parse(raw), null, 2);
console.log(pretty);
// {
// "user": {
// "id": 7,
// "name": "Nia"
// },
// "roles": [
// "reader",
// "editor"
// ]
// }
// Back to a single line:
const compact = JSON.stringify(JSON.parse(pretty));Format JSON from the terminal
Python ships with a formatter, and it works on any machine that has Python 3 installed. Pipe text in, and read the result from standard output. The default indent is four spaces, and you can change it with the --indent flag.
If you have jq installed, the plain filter . formats its input with two-space indentation and colors the output when writing to a terminal. The -c flag does the reverse and prints each document on one line, and -S sorts object keys, which is helpful when you want to compare two files.
# Python (4-space indent by default)
echo '{"id":7,"tags":["a","b"]}' | python3 -m json.tool
# Two spaces instead
python3 -m json.tool --indent 2 response.json
# jq: pretty print, compact, and sorted keys
jq . response.json
jq -c . response.json
jq -S . response.json > response.sorted.jsonChoosing an indent size
Two spaces is the most common choice for JSON, and it keeps deeply nested documents from running off the right edge of your screen. Four spaces is the Python default and is easy to read for shallow data. Tabs are a legitimate choice if your team prefers them, since the tab character is valid whitespace in JSON. The data is the same in all cases, so pick whatever matches the files already in your repository and stay consistent. Mixed indentation inside a single committed file makes diffs noisy.
A practical rule for teams is to let a tool decide. Run the same formatter in a pre-commit hook or in CI, and nobody has to argue about it in review. Editors can usually format JSON on save too, and the result matches what the command line produces as long as the indent settings agree. When a diff suddenly shows every line of a file as changed, the cause is almost always a change of indent or line endings rather than a change of data.
One quirk worth knowing: JSON.stringify with indentation puts every array element on its own line, even for short arrays of numbers. A coordinate pair becomes four lines. That is correct, just not always pretty, and it is the reason some people write a custom formatter for data files that hold lots of small arrays.
When to minify instead
Minifying removes the optional whitespace to shrink a document. It matters when JSON is sent over a network at volume, embedded in an HTML attribute or a URL, or stored in a column where every byte counts. For a typical API response, gzip or Brotli compression on the transport removes most of the whitespace overhead anyway, so minification adds only a little on top. Do not minify files that humans will edit, such as configuration committed to version control.
Sorting keys is a separate decision. JSON objects are unordered by definition, so sorting does not change meaning, but it does change the text. It is a good idea for generated files you want to diff cleanly and a bad idea if a reader expects keys in a deliberate order, such as name before version in a manifest.
Format in the browser and keep exploring
For a one-off, a browser tool is quicker than writing a script. In View My JSON you paste the text or drop a .json file, press Format, and the document is re-indented in place. If the input is invalid, the Validate step points to the problem instead of producing output. The text is parsed locally in the browser, which is worth appreciating when the response contains data you would rather not upload anywhere.
Formatted text is only a starting point. After formatting a large payload, switching to the Tree view lets you fold away the branches you do not need, and the Table view suits arrays of similar records. Between those, you can usually find the field that matters in seconds rather than scrolling through hundreds of indented lines.
Common problems when formatting
If formatting fails with an error about an unexpected token, look at the position the parser reports and check the characters just before it. Typical culprits are a trailing comma, a missing quote, an unescaped quote inside a string, or a pasted log line with a timestamp prefix in front of the JSON. If the document is truncated, the error is usually reported at the very end, as an unexpected end of input.
Also watch out for large integers. If you parse and re-stringify in JavaScript, a number like 12345678901234567890 will be rounded to the nearest double. A formatter that works on the text directly can avoid this, but one that goes through JSON.parse cannot. When exact IDs matter, check the output against the original.