How to use
- Paste JSON into the left box. It is parsed on every change, so there is nothing to press.
- Choose Format for indented output or Minify for one line; under Indent, pick 2 spaces, 4 spaces or Tab.
- Tick Sort keys alphabetically when two documents need to be compared side by side.
- If the input is invalid, the failing line is marked red in the input box and the status bar gives the line and column; click the status bar to jump there. The output appears as soon as the JSON parses.
- Copy to clipboard or Download .json. Ctrl+Enter in the input box also copies.
What this tool checks
JSON looks like JavaScript but is stricter: keys must be double-quoted, trailing commas are not allowed, and values are limited to strings, numbers, booleans, null, objects and arrays. A single misplaced comma or a stray single-quote is enough to break a whole payload, and the resulting error from most languages' JSON parsers only gives a byte offset. This tool converts that into a line and column you can actually find, and beautifies valid JSON so nested structures are easy to read.
Minifying does the opposite: it strips every non-significant space and newline, which is what you want before sending JSON over the wire or pasting it into a field with a size limit. Both directions use the browser's native parser, so a 4 MB document formats in around a tenth of a second on a laptop, and typing is debounced so the page never stalls mid-keystroke.
Example
Paste a compact object:
{"name":"Ada","born":1815,"tags":["math","writer"]}and Format produces:
{
"name": "Ada",
"born": 1815,
"tags": [
"math",
"writer"
]
}Options explained
- Format parses the input and re-emits it with one value per line, nested by the chosen indent. Key order is kept exactly as written unless sorting is on.
- Minify does the same parse and emits it with no whitespace at all:
{ "a" : [ 1 , 2 ] }becomes{"a":[1,2]}. The Indent menu is disabled while Minify is selected because it has no effect. - Indent: 2 spaces / 4 spaces / Tab sets the indentation unit for Format. Tab inserts a real tab character, which some editors display as 8 columns.
- Sort keys alphabetically reorders the keys of every object at every depth, in code-point order, so
Zebrasorts beforeapple. Arrays keep their order and no value is changed. - Load sample fills the input with a small nested object; Clear empties it.
- Colours: both the input and the result show keys, strings, numbers,
true/falseandnullin their own colours, the input while you type. If the input does not parse, its failing line is tinted red in place. An input over 100,000 characters stays plain so typing stays instant (the result is coloured up to 200,000). - Summary: above the result, the key count (across every level), nesting depth, longest array and number of values, so the shape of a large response is visible before reading it.
- Tree view: collapsible nodes; click any value to copy its JSONPath. The filter box keeps only keys and values containing your text (a matching key keeps its whole subtree), and Expand all / Collapse all open or fold every node.
Edge cases and common errors
- Trailing comma:
{"a": 1,}is valid in a JavaScript object literal but not in JSON. Reported as “Expected double-quoted property name (line 1, column 9)”: the column points at the closing brace after the comma. - Single-quoted or unquoted keys.
{'a': 1}and{a: 1}both fail with “Expected property name or '}' (line 1, column 2)”. If the text uses single quotes andTrue/None, it is a Python literal rather than JSON, and the Python Dict to JSON converter reads that directly. - Comments and second documents: JSON has no comment syntax, and a file holds exactly one value.
// noteafter the JSON, or two objects pasted one after the other, both fail with “Unexpected non-whitespace character after JSON at position 9 (line 1, column 10)”. - NaN, Infinity, undefined: none of these are JSON values; they are reported as an unexpected token at the position of the first letter.
- Byte-order mark. A file saved by Windows Notepad can start with an invisible U+FEFF, reported as an unexpected token at line 1, column 1. Delete the first character, or run the text through the AI Text Cleaner, which strips it.
- Duplicate keys are not an error.
{"a": 1, "a": 2}formats as{"a": 2}: the last value wins silently, which is also whatJSON.parsedoes in every browser. Check for this by hand if the document was assembled by concatenation. - Numbers are 64-bit floats.
{"id": 12345678901234567890}comes out as{ "id": 12345678901234567000 };0.1000becomes0.1,-0becomes0, and1e400becomesnull. IDs above 253 need to be strings. - Empty or whitespace-only input simply clears the output and shows no error, since there is nothing to report until you paste something.
- Unicode round-trips:
"é"is emitted as"é", and emoji and CJK text are kept as typed. - Absurd nesting. Ten thousand nested arrays parse, but re-serialising them overflows the browser's call stack, so the tool reports “The document is nested too deeply to format (several thousand levels)” instead of freezing. Real documents never come close; this only happens with generated input.
Do the same thing in code
JavaScript
const pretty = JSON.stringify(JSON.parse(text), null, 2);
const compact = JSON.stringify(JSON.parse(text));Python
import json
pretty = json.dumps(json.loads(text), indent=2)
compact = json.dumps(json.loads(text), separators=(",", ":"))Shell
jq . file.json # pretty-print (jq)
jq -c . file.json # compact
python -m json.tool file.json