The Complete Guide to JSON Formatting
Most JSON you encounter in the wild — API responses, webhook payloads, Terraform state files — arrives as a single unbroken line. This guide covers why formatting matters, when to minify instead, how key filtering helps inspect large payloads, and how JSON formatting fits into your dev workflow.
Why format JSON
Minified JSON from an API response looks like this:
{"users":[{"id":1,"name":"Alice","roles":["admin","editor"],"settings":{"theme":"dark","notifications":{"email":true,"sms":false}}}]}
That's technically valid, but good luck tracing where notifications is nested. Formatted with indentation, the structure jumps out:
{
"users": [
{
"id": 1,
"name": "Alice",
"roles": ["admin", "editor"],
"settings": {
"theme": "dark",
"notifications": {
"email": true,
"sms": false
}
}
}
]
}
Now you can see nesting depth, array boundaries, and object groupings at a glance. Formatted JSON is essential for debugging API responses, reading config files, and reviewing JSON changes in pull requests where diffs need to be meaningful.
Minification: when and why
Minification strips all whitespace — spaces, tabs, newlines — leaving only the data. A 100 KB prettified JSON config might shrink to 60 KB minified. With gzip, the gap narrows (gzip handles repetitive whitespace well), but the difference still matters at scale.
Use minification for:
- API response payloads — every byte counts when you're serving thousands of requests per second
- localStorage and sessionStorage — browsers cap these at 5–10 MB; minified JSON stretches that budget
- Network transfer — smaller payloads mean faster TTFB, especially on mobile connections
- Embedded JSON in HTML — inline
<script>blocks with JSON data benefit from smaller size
Don't bother minifying JSON that humans read regularly (config files in a repo, fixture data in tests). The readability loss isn't worth the disk savings.
Filtering by key
Large API payloads often contain the two fields you care about buried inside hundreds of lines of metadata, nested objects, and repeated array entries. Key filtering lists the object keys found in the JSON so you can keep specific fields, or remove fields you do not want in the output.
For example, selecting id and email:
{
"users": [
{
"id": 1,
"name": "Alice",
"email": "alice@example.com",
"role": "admin"
}
],
"meta": {
"requestId": "req_123"
}
}
Produces:
{
"users": [
{
"id": 1,
"email": "alice@example.com"
}
]
}
Use Keep when you want a focused slice of a response. Use Remove when the payload is mostly useful but contains noisy fields like debug, trace, password, or token.
The filter matches exact key names at any depth. It is intentionally simpler than JSONPath: id matches every id key, while user.id only matches a literal key named user.id.
JSON formatting in your workflow
Every language and tool has a built-in way to format JSON:
// JavaScript / Node.js
JSON.stringify(obj, null, 2);
# Python
import json
json.dumps(obj, indent=2)
# Command line (jq)
echo '{"a":1}' | jq .
In VS Code, open a .json file and hit Shift+Alt+F (or right-click → Format Document). Prettier handles JSON files too — add "tabWidth": 2 to your config and it formats on save.
JSON.stringify replacer and space parameters
JSON.stringify takes three arguments: the value, a replacer, and a space (indentation). Most developers only use the first and third:
JSON.stringify(obj, null, 2); // pretty-print with 2 spaces
The replacer is a function or array that filters or transforms values during serialization. A practical use — redacting sensitive fields before logging:
JSON.stringify(
obj,
(key, value) => (key === "password" ? "[REDACTED]" : value),
2
);
Or pass an array to include only specific keys:
JSON.stringify(obj, ["id", "name", "email"], 2);
Sorting keys
Some formatters sort object keys alphabetically. This is useful for deterministic output — sorted keys produce stable diffs, consistent cache keys, and predictable test snapshots.
But the JSON spec (RFC 8259) says object key order is not guaranteed, so don't write code that depends on it. Parsers may reorder keys internally. This tool preserves insertion order by default, which matches what JSON.parse and JSON.stringify do in JavaScript engines.
Troubleshooting
Formatted output has different key order than the original — If you pasted JSON that was serialized by a language or library that sorts keys (Python's json.dumps(sort_keys=True), for example), the order you see is the serialization order, not an inherent property of the data. This tool preserves the order it receives. If you need sorted keys, sort before pasting.
Large JSON files are slow to format — Browser-based formatters parse and re-serialize in the main thread. Files over 10 MB can cause noticeable lag. For very large files, use command-line tools like jq or python -m json.tool which handle streaming and memory more efficiently.
Unicode escape sequences show as \uXXXX instead of actual characters — JSON.stringify escapes certain Unicode characters by default. If you see \u00e9 instead of é, the data is valid — it's just escaped. Most parsers decode these automatically. This tool displays the parsed output, so escaped sequences resolve to their actual characters.
Trailing commas cause parse errors — JSON does not allow trailing commas. {"a": 1,} is invalid. This is a common mistake when copying from JavaScript objects (which do allow trailing commas). Remove the trailing comma before formatting, or use a JSON5-aware parser if your toolchain supports it.
Nested arrays or objects appear collapsed on one line — Some formatters collapse short arrays (like [1, 2, 3]) onto a single line for compactness. Standard JSON.stringify with a space argument always expands every level. If you need consistent expansion, use a formatter that doesn't apply compact rules.