JSON Formatter & Validator

JSON Input
Formatted Output

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:

WrittenWhy 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} // noteJSON 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.

1. Duplicate keys are accepted, and the last one wins. The JSON specification does not require parsers to reject a repeated key, and JavaScript's does not. Formatting {"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.
2. Integer-like keys are reordered ahead of everything else. JSON objects are unordered by specification, but every parser in practice preserves insertion order — except for keys that look like array indices. Format {"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.
3. Large integers silently lose precision. JSON numbers have no size limit, but JavaScript parses them into 64-bit floats, which hold integers exactly only up to 253−1. A 20-digit Twitter-style snowflake ID or a Postgres 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.
4. Escapes are decoded, so the output is shorter than the input. "é" 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.

Working with JSON at scale? Serverless Postgres platforms like Neon and Supabase index 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

Is my JSON uploaded anywhere?
No. Parsing, formatting, and validation all run in JavaScript in your browser. Nothing is transmitted, stored, or logged, so it is safe to paste production API responses.
Why does the formatted output differ from my input beyond whitespace?
Because formatting is a parse followed by a re-serialise, not a text transformation. Unicode escapes are decoded, duplicate keys collapse to the last occurrence, and integer-like keys move to the front. The data is equivalent; the bytes are not.
Can it format a single value rather than an object?
Yes. Since JSON became RFC 8259, any value is a legal document — 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.
What does "max depth" mean?
The deepest level of nesting in the document, counting from zero at the root. It is a fast sanity check: a payload you expected to be flat reporting a depth of six usually means it arrived wrapped in an envelope you did not account for.
Will it repair broken JSON automatically?
No, by design. Guessing where a brace belongs risks producing a document that parses but means something you did not intend. The tool tells you the line and column and leaves the fix to you.
Is there a size limit?
No hard limit — you are bounded only by your browser's memory. Files of a few megabytes format without trouble; very large documents may briefly freeze the tab while parsing.