How to format and check JSON
- Paste your JSON into the box, or drop a
.jsonfile on the page. - Read the line under the box. If the text is valid it says so and counts the objects, arrays and keys; if not, it names the problem and points at the character.
- Pick a layout — two spaces, four spaces, tabs or minified — and tick Sort keys if you want every object in alphabetical order.
- Copy the result or download it as
formatted.json.
A formatter should not change your data
The shortest way to write a JSON formatter is to parse the text and print it back. It is also the way that quietly changes things, because parsing turns every number into a JavaScript double. Give it this array and see what comes back:
[12345678901234567890, 9007199254740993, 1.0, 1E5, 1e999]
→ [12345678901234567000,9007199254740992,1,100000,null]
That second line is what JSON.stringify(JSON.parse(text)) returns in Chrome,
checked here rather than assumed. The first two numbers lost their last digits, the next
two changed the way they are written, and the last became null. An order
number, a database id or a 19-digit timestamp in nanoseconds does not survive that. How often it happens depends on the kind of ID: we ran 470,000
simulated ones through JSON.parse and wrote up
which ones change and which do not.
This page reads the text into its own tree that keeps each number and string exactly as written, and prints those. The output above stays as you typed it. Numbers that a JavaScript program could not hold exactly are listed with what JavaScript would turn them into, so you find out before a script does it for you.
Duplicate keys disappear without a warning
{"a":1,"a":2} is legal JSON. The standard only says keys
should be unique, and most parsers then keep the last one:
JSON.parse returns a as 2 and the 1 is gone. Merged config
files and hand-edited exports produce duplicates all the time, and a formatter built on
JSON.parse repairs them by deleting data.
Here each duplicate is listed with its path and both line numbers —
$.b.c (lines 2 and 3) — and stays in the output so you choose which
to keep. Two spellings of the same key, "a" and "a", are
the same key to a parser, and the report says so.
Errors that say what is wrong
The parser is written to explain, not just to refuse. The message names the usual
causes: a trailing comma, single quotes, an unquoted key, a comment, a missing comma
between two items, NaN or undefined, a number with a leading
zero, a raw line break inside a string, an object that is never closed. The line and
column are given, a pointer sits under the exact character, and Go to the
error selects it in the box. If another document begins where the first ended,
it says the text looks like JSON Lines — one document per line — which is a
different format from a single JSON file.
How it was checked
The result was compared with Python's json module rather than with itself.
Sixty randomly generated documents, containing accents, Chinese characters, emoji,
escapes and integers past 264, were formatted in all four layouts and matched
json.dumps character for character, and sorted output matched
sort_keys. A further 73 tricky inputs — [01],
[1.], {"a":1,}, ["\x"], [NaN], a
raw tab in a string and the like — were accepted or rejected exactly as Python
accepts or rejects them. A 7 MB document with 60,000 records was parsed and formatted
in about 0.7 seconds and came out identical to Python's output.
Comments and trailing commas
Standard JSON has neither. Files such as tsconfig.json and VS Code settings
do, and they are read by tools that accept a looser dialect often called JSONC. Tick
Accept comments and trailing commas to read those; the page counts what
it removed, because the formatted result is strict JSON and the comments are not carried
over. With the box unticked they are errors, which is what a strict parser such as
JSON.parse will say.
Related tools
Turning JSON into a spreadsheet? JSON to CSV collects columns from every record, and JSON to XML reports names that collide. Working with times inside the data? The Unix timestamp converter reads whole columns of them. Nothing you paste is uploaded.