JSON Formatter & Validator
How to Format and Validate JSON
Paste JSON into the left panel. Formatting happens as you type, so a valid document is beautified immediately and an invalid one reports the problem in the status strip above the panels. Use Minify to strip every byte of insignificant whitespace, Sort keys to order object keys alphabetically at every nesting level, and the indent selector to switch between two spaces, four spaces, and tabs.
Everything runs in your browser. Your JSON is never uploaded, logged, or sent to a server — which matters, because the JSON developers most often need to inspect is an API response containing customer records, internal hostnames, or a bearer token. You can confirm this by opening your browser's network tab and formatting a document: there are no outbound requests.
Reading the Error Message
An invalid document reports the parser's own message in the status strip. Most failures come with a character offset — position 412 — which is useless when you are looking at a 400-line file in an editor that counts lines, not bytes, so this tool converts that offset into a line and column you can navigate to.
Not every message carries one. Browsers report an unquoted bare word such as {"a": oops} or {"a": NaN} with a snippet of the surrounding text and no offset at all, because the parser cannot say which token you meant. In those cases you get the snippet, which is usually enough to find the line by searching for it.
One habit saves a lot of time regardless: JSON parsers report where they noticed the problem, not where you made it. A missing closing brace is reported at the end of the document, because that is the first point at which the file became unsalvageable — feed this tool {"a": {"b": 1} and it points at the last line, not the second. When the reported position looks innocent, the real defect is almost always an unclosed brace, bracket, or quote further up.
What JSON Does Not Allow
JSON is a deliberately small format, and most "why won't this parse" questions come down to writing JavaScript rather than JSON. These are rejected outright:
| Written | Why it fails |
|---|---|
{"a": 1,} | Trailing commas are invalid. JavaScript allows them; JSON never has. |
{a: 1} | Keys must be double-quoted strings, always. |
{'a': 1} | Single quotes are not string delimiters in JSON. |
{"a": 1} // note | JSON has no comment syntax of any kind. |
{"a": NaN} | NaN, Infinity, and undefined are not JSON values. |
{"a": .5} | Numbers need a leading digit — write 0.5. |
{"a": 0x1F} | Hex, octal, and binary literals do not exist in JSON. |
The last three catch people migrating a JavaScript config object into a .json file. If you want comments and trailing commas, you want JSON5, JSONC, or YAML — and our YAML to JSON converter handles the conversion in both directions when a commented config needs to become strict JSON.
Four JSON Behaviours That Surprise People
These are not parser bugs. They are the specification and the JavaScript object model doing exactly what they promise, in ways that quietly change your data.
{"env":"staging","env":"production"} returns a single key with the value "production" — the earlier entry vanishes with no warning at all. Two config fragments concatenated by a script is the usual way this happens, and the failure is silent in every direction. This is stricter in YAML, where a duplicate key is a spec violation that good parsers reject.
{"b":1,"2":2,"a":3,"1":4} and the output comes back with "1" and "2" first, in numeric order, followed by "b" and "a" in their original order. This is a JavaScript object property-order rule, not a formatting choice, and it bites anyone using numeric IDs as object keys and diffing the result.
bigint comes back rounded. Anything that must survive a round trip — IDs, account numbers, cursors — should be transmitted as a string. This is why so many APIs return "id": "12345678901234567890" in quotes and it looks like a mistake. It is not.
"é" becomes é and "café" becomes café, because the escape and the character are the same value — the parser resolves it and the serialiser emits the shortest valid form. Only ", \, and control characters below U+0020 are re-escaped on output. The document is equivalent; it just will not be byte-identical, which matters if something downstream is comparing checksums.
Minify or Format?
Formatting and minifying produce the same data, so the choice is entirely about what reads or transmits it. Format for anything a human will look at or a version control system will diff — a minified file shows up as one enormous changed line, which makes code review impossible. Minify for anything crossing a network, being embedded in a build artifact, or stored in a column where size is billed.
The saving is real but usually smaller than expected, because gzip and Brotli are extremely good at compressing repeated whitespace. On a typical API payload, minification cuts 15–30% of the raw bytes and considerably less after compression. It is worth doing on the wire and not worth arguing about at rest.
Sorting Keys, and Why It Makes Diffs Readable
Two JSON documents can be semantically identical and textually completely different, because key order is not meaningful but is preserved. When a tool regenerates a lockfile, a manifest, or an exported configuration, keys can come back in a different order and produce a 400-line diff describing zero actual changes.
Sorting both documents alphabetically before comparing collapses that noise, leaving only real differences. This tool sorts recursively at every level and deliberately never reorders arrays, because array order is data — reordering ["read","write"] would change meaning. Sort keys on both sides, then diff.
Where JSON Formatting Comes Up
Debugging an API response. A minified response body copied from the network tab is unreadable. Formatting reveals the structure, and the key and depth counts tell you immediately whether you received the object you expected or an error envelope wrapping it. If the response carries a bearer token, our JWT decoder will show you its claims and expiry without sending it anywhere.
Fixing a config file a machine wrote. Generated tsconfig.json, composer.json, and cloud policy documents are frequently emitted minified or with inconsistent indentation. Format, then commit — future diffs stay small forever.
Checking data before it goes into a database. Validating a payload before it hits a jsonb column catches malformed input at the boundary rather than as a constraint violation halfway through a migration. Timestamps inside those payloads are usually epoch integers; our Unix timestamp converter turns them into readable dates.
jsonb columns directly, so you can query nested keys without unpacking documents in application code. These are affiliate links — they cost you nothing and help keep these tools free.
Frequently Asked Questions
42, "hello", true, and null all validate on their own. The status strip names the root type so you can confirm you got the shape you expected.