JSON Formatter & Validator

Format, validate and minify JSON in your browser. 2/4/tab indent, sort keys, exact line and column errors, and big-integer safe mode. Nothing is uploaded.

Runs in your browser

Paste JSON or drop a .json file — it is parsed by your own browser and never uploaded.

Drop a file here or click to browse
Drop a .json file — it is read locally, never uploaded. Files never leave your device.

Formatting and validation run with your browser’s own JSON parser. Nothing is uploaded. · Ctrl/Cmd + Enter to re-format

Result

Paste JSON on the left, or drop a .json file.

What formatting JSON actually does

JSON is defined by RFC 8259 and ECMA-404, and in that grammar the whitespace between tokens carries no meaning at all. Formatting therefore parses your text into a value and writes it out again with the indentation you picked — it never edits the characters in place. Whatever survives the round trip is data; whatever disappears was never part of the document.

That round trip is why formatting doubles as validation. If the parser refuses the input you get a line, a column and a caret instead of output, so a successful format is proof that the document is well-formed JSON rather than merely plausible-looking text.

Two changes are deliberate. Duplicate keys collapse — RFC 8259 leaves them undefined and JavaScript keeps the last one — so a key that vanishes was declared twice. And keys that look like non-negative integers ("0", "12") are emitted in numeric order ahead of the others, because that is how JavaScript objects order their properties.

Beautify or minify: which output to take

Indented output is for humans and for diffs: two spaces is the default across the npm and JavaScript ecosystem, four spaces is common in Python and .NET tooling, and a tab keeps the file aligned with Go and Makefile conventions. Whichever you choose, use the same one across a repository so version control shows content changes rather than whitespace churn.

Minify strips every optional space and newline and reports how many bytes that saved. On a pretty-printed config file the saving is typically 20–40 %, but on the wire it matters far less than it looks: gzip and Brotli compress repeated indentation almost to nothing, so minifying a response that is already compressed buys single-digit percentages.

Minifying is worth it where compression does not reach: a JSON blob embedded in a data attribute, a value stored in localStorage or a database column, or a payload counted against a size limit such as a cookie, a query string or an SQS message.

Reading a JSON syntax error

An invalid document produces a line, a column, the offending source line and a caret under the exact character. The position comes from the engine when it reports one and from our own scanner otherwise, because V8, SpiderMonkey and JavaScriptCore word the same failure differently — "Unexpected token }" in one browser is "JSON.parse: expected property name" in another.

Almost every real-world failure is one of these:

  • A trailing comma before } or ] — legal in JavaScript, never in JSON.
  • Single quotes, or unquoted keys ({name: 1}) — JSON strings and keys need double quotes.
  • // or /* */ comments: JSONC and JSON5 allow them, RFC 8259 does not. Strip them, or keep the file as .jsonc and format the stripped copy.
  • NaN, Infinity, undefined, or Python’s True / False / None instead of true / false / null.
  • A raw newline or tab inside a string: every character below U+0020 must be escaped as \n, \t or \u00XX.
  • Several objects pasted one after another (NDJSON / JSON Lines): that is a stream of documents, not one document.

Sorting keys and comparing two files

Sorting orders object keys with a numeric-aware collator, so item2 lands before item10 instead of after it. "Include nested objects" applies the same order at every level. Array order is never touched: in JSON the position of an array element is data, and reordering it changes the document’s meaning.

This is what makes two exported files comparable. Format both with the same indent and sorted keys, then run the two outputs through Text Diff: what remains is the change you were looking for, with no noise from a serialiser that emitted keys in a different order.

Big integers, floats and other precision traps

JSON numbers have no size limit, but JavaScript reads every one of them into a 64-bit double, which is exact only up to 9,007,199,254,740,991 (2^53 − 1). A 64-bit Snowflake ID such as 7223372036854775807 comes back as 7223372036854775800 — a valid-looking value that points at no record. "Preserve big integers" keeps those literals verbatim, as strings.

Fractions have the same problem in a quieter way: 0.1 + 0.2 is 0.30000000000000004, and a literal written as 1.0 or 1e2 is re-emitted as 1 or 100 because the double carries no memory of how it was typed. Money and measurements survive best as strings or as integer minor units (cents, won), never as floats.

The warning above the output counts the integer literals in your input that cannot survive a double, so you can see the risk before you copy the result into a ticket or a test fixture.

What the statistics tell you

Keys counts every object member in the document, arrays counts every array, and depth is the deepest level of nesting. Depth is the practical one: many schema validators, database JSON columns and API gateways cap nesting (commonly between 32 and 100 levels), so a document that formats here can still be rejected downstream.

Input bytes, output bytes and the saved percentage are UTF-8 byte counts, not character counts — the difference matters as soon as the document contains Korean, emoji or accented Latin, where one character costs two to four bytes.

Where your JSON goes (nowhere)

Parsing, sorting, minifying and the error scan all run in this tab with the browser’s own JSON parser. There is no upload, no account and no "load from URL" button — fetching a URL would require a server to make the request on your behalf, which is exactly the property this page is built to avoid.

Your draft is kept in this browser’s localStorage so a reload or an accidental tab close does not lose it. It stays on this device, is readable only by this site, and the Clear button removes it — worth pressing on a shared or public machine.

How to use

  1. Paste JSON into the left box, drop a .json file, or press ‘Load sample’ to try it out.
  2. Choose an Indent: 2 spaces, 4 spaces, Tab, or Minify to strip every space.
  3. Tick ‘Sort keys’ (and nested objects), or ‘Preserve big integers’ to keep digits past 2^53.
  4. If the JSON is invalid, read the line and column in the error and use the go-to-line button.
  5. Copy the formatted JSON from the output box, or press ‘Download .json’ to save it.

FAQ

Is my JSON uploaded to a server?

No. Formatting, validation and minifying all run in your browser with the native JSON parser. There is no upload and no "save" feature — the page never sends your data anywhere. Open DevTools → Network and watch: nothing leaves after the page loads.

Why do my large ID numbers change after formatting?

JavaScript numbers lose precision above 9,007,199,254,740,991 (2^53−1), so Snowflake-style IDs get rounded. Turn on "Preserve big integers" and we keep those literals exactly as they appear, as strings.

Can I load JSON from a URL?

No, and that is deliberate. Fetching a URL would require our server to make the request for you, which breaks the promise that your data never leaves your browser. Paste the JSON or drop the file instead.

Why did one of my keys disappear after formatting?

It was declared twice in the same object. RFC 8259 says nothing about duplicate names, and JavaScript keeps the last occurrence, so {"a":1,"a":2} formats as {"a":2}. It is a genuine bug in whatever produced the file — the second value has been silently winning in every consumer, not just here.

Can I format JSON Lines (NDJSON) or a file with comments?

Not as one document — neither is JSON. NDJSON is one complete JSON value per line, so paste a single line at a time (or wrap the lines in [ ] with commas between them). For .jsonc or tsconfig-style files, remove the // and /* */ comments first; RFC 8259 has no comment syntax, and a formatter that accepted them would hand you output your own parser then rejects.

Related tools

More Developer tools: Developer

Send feedback

Found a bug or have an idea? Tell us — it helps make the tools better.

Only needed if you would like a reply.

Page: /developer/json-formatter/