Formatting JSON: Pretty-Printing and Minifying

Beginner
9 min

Formatting JSON: Pretty-Printing and Minifying

The same JSON document can be written on a single line with no spaces or spread across dozens of indented lines. Both forms are valid and carry identical data; the difference is who reads them. In this lesson you will learn how to pretty-print JSON for humans and minify it for machines using JavaScript, Python, the command line and your editor, and when each form is the right choice.

Whitespace Is Insignificant

The JSON grammar allows four whitespace characters between tokens: space, tab, line feed and carriage return. A parser ignores all of them, so the minified and the indented version below are equal after parsing:

json
{"id":1042,"items":[{"sku":"A-1","qty":2}],"paid":false}
json
{ "id": 1042, "items": [{ "sku": "A-1", "qty": 2 }], "paid": false }

Whitespace inside a string is significant: "New York" and "New York" are different values. Formatters only touch the whitespace between tokens.

Pretty-Printing in JavaScript and Python

JSON.stringify takes a third argument called space. A number from 1 to 10 sets the indentation width; a string of up to 10 characters is used verbatim as the indent unit.

javascript
const user = { name: "Ada", roles: ["admin", "dev"], active: true }; JSON.stringify(user); // {"name":"Ada","roles":["admin","dev"],"active":true} JSON.stringify(user, null, 2); // indented with two spaces JSON.stringify(user, null, "\t"); // indented with tabs

The second argument (null here) is the replacer, covered in the next lesson. Python's json.dumps uses keyword arguments instead:

python
import json user = {"name": "Ada", "roles": ["admin", "dev"], "active": True} print(json.dumps(user, indent=2, sort_keys=True)) print(json.dumps(user, separators=(",", ":"))) # smallest possible output

Python's default output, {"name": "Ada", ...}, keeps a space after each separator, so it is neither minified nor pretty. Pass separators=(",", ":") when size matters.

Formatting from the Command Line

You will constantly inspect API responses and config files in a terminal. Three tools cover almost every case:

| Task | jq | Python | |------|----|--------| | Pretty-print | jq . data.json | python -m json.tool data.json | | Minify | jq -c . data.json | python -m json.tool --compact data.json | | Sort keys | jq -S . data.json | python -m json.tool --sort-keys data.json | | Custom indent | jq --indent 4 . or jq --tab . | python -m json.tool --indent 4 |

jq is the most convenient because it also validates: a malformed file produces an error with line and column and a non-zero exit code. Pipe anything into it:

bash
curl -s https://api.example.com/users/1 | jq . jq . config.min.json > config.json

In editors the same job is a shortcut: VS Code formats a JSON document with Shift+Alt+F (Shift+Option+F on macOS), and Prettier handles whole projects with npx prettier --write "**/*.json".

When to Minify and When to Pretty-Print

Minified JSON is smaller, but the saving is often less than expected. Web servers gzip or brotli-compress responses, and whitespace compresses extremely well, so the difference on the wire is usually a few percent.

  • Pretty-print files that humans edit or review: configuration, fixtures, test snapshots, documentation examples. Two-space indentation is the convention in the JavaScript ecosystem; four spaces is common in Python and Java projects. Consistent formatting also yields readable git diffs, where a one-key change is a one-line change.
  • Minify what machines exchange or store in bulk: API responses, queue messages, log lines, localStorage values, and JSON Lines files, where each record must occupy exactly one line.

Key order is not part of the JSON data model, so {"a":1,"b":2} and {"b":2,"a":1} are the same object. Sorting keys (jq -S, sort_keys=True) is still useful because it produces a canonical form that is easy to diff, compare or hash.

Common Mistakes

  • Formatting the string instead of the value. JSON.stringify(text, null, 2) wraps an already-serialized string in more quotes. Parse first: JSON.stringify(JSON.parse(text), null, 2).
  • Trusting indentation. A file that looks well nested can still miss a comma or bracket. Validate with a parser, not by eye.
  • Committing minified config. Nobody can review a 4,000-character line. Keep repository files pretty-printed and let the build step minify.
  • Expecting formatters to repair invalid JSON. Trailing commas and comments make jq and json.tool fail; formatters only re-space valid documents.
Quick Quiz
Question 1 of 3

What does `JSON.stringify(data, null, 2)` produce?

Key Takeaways

  • Whitespace between JSON tokens is ignored by parsers; whitespace inside strings is data.
  • JSON.stringify(value, null, 2) pretty-prints and JSON.stringify(value) minifies; Python uses indent= and separators=.
  • jq ., python -m json.tool and editor formatters pretty-print and validate files from the terminal.
  • Pretty-print files that people read and edit; minify data that machines exchange.
  • Sorting keys creates a canonical form that is easier to diff, compare and hash.

Next lesson: Advanced JSON.stringify and JSON.parse: replacer, reviver and toJSON — control exactly which properties are serialized and revive dates, BigInts and custom classes when parsing.

Formatting JSON: Pretty-Printing and Minifying - JSON | CodeYourCraft | CodeYourCraft