How JSON Indentation Works (and Why It Matters)
Whitespace is ignored by JSON parsers but essential for the humans reading JSON. Here's what's actually happening when you format JSON.
Whitespace in the JSON specification
The JSON specification (RFC 8259) defines exactly which whitespace characters are allowed and where. Section 2 of the spec lists four insignificant whitespace characters: space (U+0020), horizontal tab (U+0009), newline (U+000A), and carriage return (U+000D). These characters may appear freely between any two JSON tokens — before or after values, colons, commas, and structural characters like {, }, [, and ].
The critical word is insignificant. The spec explicitly states that insignificant whitespace is allowed before or after any structural character. A JSON parser is required to ignore this whitespace entirely when determining the value being parsed. One space, one hundred spaces, or zero spaces between a colon and its value — the parser produces the same result.
There is one important exception: whitespace inside a string value is significant. The string "hello world" has a space that is part of the value. A formatter will never add or remove whitespace within a string literal.
The two extremes: minified and formatted
To understand indentation, it helps to look at both extremes. Consider this JSON describing a user object:
Minified — zero whitespace, 83 bytes:
{"user":{"name":"Alice","age":30,"roles":["admin","editor"],"active":true}}
Formatted with 2 spaces — 150 bytes:
{
"user": {
"name": "Alice",
"age": 30,
"roles": [
"admin",
"editor"
],
"active": true
}
}
The formatted version is 81% larger in bytes, but a human can immediately see the structure: a top-level object with a user key containing a nested object, which itself contains a roles array. Both are parsed by any JSON parser to the exact same value.
How indentation scales with nesting depth
The key rule of JSON indentation: each nesting level adds one unit of indentation. With 2-space indentation, the top level has zero leading spaces, the first nesting level has 2 spaces, the second has 4, the third has 6, and so on. With 4-space indentation, those numbers double: 0, 4, 8, 12.
This means indentation choice has a compounding effect on deeply nested JSON. If your JSON has a nesting depth of 8 (common in complex API responses), 4-space indentation means the innermost values have 32 leading spaces. On a standard 80-character terminal, that leaves only 48 characters for the actual content. Two-space indentation uses only 16 spaces, leaving 64 for content — significantly more breathing room.
This is one reason why 2-space indentation is preferred for JSON specifically (as opposed to Python code, where 4 spaces is standard): JSON structures tend to nest more deeply than typical Python code.
How JSON formatters add indentation
A JSON formatter doesn't just add spaces to raw text — it must fully understand the JSON structure to do the job correctly. The process is always:
- Parse the input JSON string into an in-memory data structure (an object/dictionary, array, string, number, boolean, or null).
- Serialize that structure back to a string, this time inserting line breaks and indentation at each nesting level.
In JavaScript, this is exactly what JSON.stringify(JSON.parse(input), null, 2) does. The null argument is a replacer function (unused), and 2 is the indent size in spaces.
// The simplest possible JSON formatter
function formatJson(input, indent = 2) {
return JSON.stringify(JSON.parse(input), null, indent);
}
This approach has a side effect worth knowing: it normalizes the JSON. Key order may change (parsers are not required to preserve key insertion order, though in practice V8 and most modern engines do). Unicode escapes like é may be converted to their actual character (é) or left as-is, depending on the serializer's settings. And any invalid JSON is caught as an error during the parse step.
Choosing an indentation style
There is no universal standard for JSON indentation — it varies by language community, team, and context. The practical guidance:
- 2 spaces: Default for JSON in JavaScript, Node.js, and most web tooling.
JSON.stringify, VS Code, Prettier, and ESLint all default to 2 spaces. Good for deeply nested structures. - 4 spaces: Standard in Python (PEP 8) and common in Java, C#, and Ruby. If the JSON file sits in a Python or Java project, 4 spaces is natural.
- Tab: Enforced by Go's
gofmtand preferred in some PHP and Makefile conventions. Tabs allow each developer to configure their display width independently.
For JSON that will be checked into version control alongside source code, use whichever style the repository's .editorconfig or linter enforces. Consistency matters more than the specific choice.
Indent your JSON instantly
Paste any JSON and choose your indent size — 2 spaces, 4 spaces, or tab. Formats automatically, validates as you type.
Open JSON Formatter →Frequently Asked Questions
Does indentation affect how JSON is parsed?
No. JSON parsers treat whitespace outside of string values as insignificant. A minified JSON string and its formatted equivalent parse to exactly the same value. Indentation is purely cosmetic.
What is the standard indentation for JSON?
There is no single mandatory standard, but 2-space indentation is most common for JSON files specifically. JavaScript's JSON.stringify defaults to 2 spaces, as does VS Code's JSON formatter. Python's json.dumps defaults to no indentation but most Python style guides use 4 spaces.
How do JSON formatters add indentation?
A formatter first parses the JSON into memory (building a tree of objects, arrays, and values), then serializes it back to a string, inserting line breaks and indentation at each nesting level. In JavaScript this is exactly what JSON.stringify(JSON.parse(input), null, 2) does.
Can whitespace appear inside a JSON string value?
Yes — whitespace inside string values is significant and is preserved exactly as written. Only whitespace outside string values (between tokens and structural characters) is insignificant. A formatter will never alter whitespace within a string.