Beautify, validate, and minify JSON instantly. Paste messy JSON to format it with clean indentation, or catch syntax errors with a clear message. Nothing is uploaded.
SYSTEM ● ONLINE · LOCAL COMPUTE · ZERO UPLOAD
UNIT // JSON.FORMATLIVE
Action
—
Status
0
Keys
0 B
Size
Quick Answer
How do you format JSON?
// Answer
Paste your JSON and the formatter parses it, then re-serializes it with consistent indentation (2 spaces) so nested structures are easy to read. If the JSON is invalid, it shows the exact error. Beautify adds readable spacing; Minify strips all whitespace for the smallest size.
Why use this tool
Read and debug JSON faster
APIs, config files, and logs are full of JSON that arrives as one unreadable line. This formatter makes it legible, validates the syntax, and can minify it again for production — all locally, so even sensitive payloads never leave your machine.
FAQ
Frequently asked questions
Paste it and the tool parses it instantly. Valid JSON is formatted; invalid JSON shows a clear error message with the reason.
Beautify adds indentation and line breaks for readability; minify removes all unnecessary whitespace to reduce size.
No. Parsing and formatting happen entirely in your browser, so even confidential data stays private.
Yes, within your browser memory limits. Very large files are handled client-side without uploading.
Formatting proves one thing: the text is syntactically valid JSON. It says nothing about whether the fields are right, the values sensible, or the types what your code expects. A perfectly formatted payload can still be wrong in every way that matters.
The green Valid readout means the parser reached the end of your text without a grammar error. It does not mean the API returned the field you were looking for, that price is a number rather than the string "12.00", or that a required key is present. If you need those guarantees you need a schema check in your own code, which is a different job from the one this page does.
Worked example
What a parse-and-rewrite changes, and what this tool keeps
The quick way to reformat JSON is to parse it into a JavaScript value and write that value back out (JSON.parse then JSON.stringify). That is not a photocopier: the five things below change on the way through, without a word. This tool checks your text with the same parser but formats from your original text, so all five come through exactly as you typed them.
You paste
A parse-and-rewrite gives back
Why
{"a":1,"a":2}
{"a":2}
Duplicate keys are legal to write and impossible to keep. The last one wins, silently.
{"10":"x","2":"y","1":"w"}
{"1":"w","2":"y","10":"x"}
Keys that look like array indices are reordered into numeric order ahead of everything else.
{"id":12345678901234567890}
{"id":12345678901234567000}
A JSON number becomes a double. Past 253 the exact integer cannot be held, so the tail digits are lost.
{"a":1.0,"b":1e2,"c":1.50}
{"a":1,"b":100,"c":1.5}
Number formatting is not part of the value. Trailing zeros and exponents do not survive.
{"a":"\u0041"}
{"a":"A"}
Escape sequences are decoded into the characters they stand for.
The third row is the one that bites in production. If a payload carries a 19-digit order ID or a Twitter-style snowflake ID, a parse-and-rewrite formatter will hand you a different ID, and it will look entirely plausible. This tool keeps the digits as typed and shows a warning when a number is too large for JavaScript to hold exactly. The real fix belongs at the producer: send large identifiers as JSON strings. Until then, do not use a reformatted copy as your source of truth for those fields.
The Keys readout counts key names across every nested object and ignores array positions, so the sample payload reports 7: five at the top level plus two inside nested. Size is the formatted output measured in UTF-8 bytes, so emoji and accented letters count at their real size.
Reference
What counts as JSON, and what only looks like it
JSON is a much smaller language than most people remember. Everything in the rejected column below is something you will meet in a real config file, and all of it fails here — correctly.
Written like this
Result
{"a": 1}
Valid
{'a': 1}
Rejected. JSON strings use double quotes only.
{a: 1}
Rejected. Keys must be quoted strings.
{"a": 1,}
Rejected. No trailing comma.
// a note
Rejected. JSON has no comments, at all.
{"a": NaN}
Rejected. NaN and Infinity are not JSON numbers.
{"a": 01}
Rejected. Numbers may not carry a leading zero.
Which means this page is not a JSON5 or JSONC parser. A tsconfig.json or a .eslintrc with comments in it is not JSON and will not format here. It is also not an NDJSON reader: a file with one object per line is several documents, not one, and the parser reports an error where the second one begins.
The mistake
Editing quotes until it parses
The common failure looks like this: a paste throws Expected property name or '}' in JSON at position 1, and the reflex is to start adding and removing quotes and brackets until the error goes away. That works, in the sense that something eventually parses. It also changes the data, and you now have no idea how.
Do the opposite. The message names a character position — count to it in the input and look at what is actually there. Nine times out of ten it is a truncated copy (a log viewer clipped the line), a doubled response body, or a stray wrapping quote from a shell. Fix the copy, not the JSON. And remember the parser reports only the first problem: clearing it often reveals three more behind it.
Very large files will lock the tab
Parsing happens on the main thread, and it runs again on every keystroke in the input box. A few hundred kilobytes is unnoticeable. A multi-megabyte paste will freeze the tab while it parses, then freeze it again each time you type a character into it. That is not a bug to work around in the browser — for files that big, reformat them once on the command line and bring the interesting fragment here. If your aim is only to shrink a payload, the dedicated JSON minifier does the stripping without the pretty-printing pass.
Privacy
Why it matters that this one runs locally
Picture the ordinary case. Something is failing at 02:00, and an engineer copies the body of a rejected webhook out of a log to read it properly. That body holds a customer's email address, a delivery address, an order total, and — because it is a webhook — quite possibly a signing secret or a bearer token in the same blob.
Pasting that into a formatter hosted by a stranger is not a convenience. It is a disclosure of personal data and a live credential to an unknown third party, it is now in someone else's request log, and under most incident-response policies it is the sort of thing that has to be written up. The convenient tool created the incident.
This page cannot do that. The script behind it is short and contains no fetch, no XMLHttpRequest and no image beacon — you are welcome to read it. The test anyone can run in ten seconds: load the page, switch off your Wi-Fi, and paste. It still formats, because there was never a server in the path.
Once the payload is readable, the neighbouring tools work the same way on the same data. JSON to CSV flattens an array of records for a spreadsheet, JSON to YAML is useful when the destination is a config file, and JSON to TypeScript turns a sample response into interfaces so the shape is at least checked at compile time. If the payload turns out to be a token rather than a document, the JWT decoder is the right stop. The rest of the set is on the developer tools page.