Advanced JSON Formatter
Validate, format, and explore your JSON data instantly. 100% Client-side.
About the JSON Formatter
Paste JSON into the left pane and the right pane fills in as you type. There is no button to press first, though Pretty Print re-runs the pass on demand. The document goes through the browser’s own JSON parser and is printed straight back out at the indentation you picked, so what you see on the right is your data re-laid out — never a repaired or guessed-at version of what you typed. If it does not parse, the parser’s own complaint appears instead.
Indentation, minifying and the two counters
The indentation picker offers a tab character or two, four, six or eight spaces, and changing it reformats immediately. Minify goes the other way, stripping every space and newline so the document collapses onto a single line. Output always uses newline line endings regardless of what the input used, and the pane is read-only: edits belong on the left.
The two figures in the toolbar describe whatever is currently in the output pane. The first is its size in bytes measured as UTF-8, so an accented letter counts as two and an emoji as four. Pretty print, read the number, minify, read it again, and the difference is exactly what indentation is costing you on the wire. The second counts values rather than lines: every object, array, string, number, boolean and null in the document, the top level included. {"a": 1, "b": [1, 2]} counts as five — the object, the number, the array and its two entries. Keys are not counted separately, and the figure stays put when you minify, because minifying changes the layout and not the data.
How invalid JSON is reported
A failed parse puts a red bar under the toolbar carrying the parser’s own message, unedited and in a monospace font. On Chromium browsers that reads something like Expected ',' or '}' after property value in JSON at position 7 (line 2 column 1); Firefox and Safari word it differently but also give you a line and column. Read the position as where the parser gave up, not as where you went wrong — a comma missing at the end of one line is reported at the start of the next.
While the input is broken the output pane keeps the last result that did parse, so you still have something to refer to. Emptying the input clears both panes and resets the counters. One failure worth naming: a file saved with a UTF-8 byte-order mark fails immediately at position 0 even though the text looks perfect. Re-save it without the BOM.
Strict JSON, one document at a time
The parser here is the browser’s, which implements the JSON standard exactly and forgives nothing. There is no support for // or /* */ comments, trailing commas, single-quoted strings, unquoted keys, hexadecimal numbers or theNaN and Infinity literals. That rules out the JSON-shaped config dialects: a JSONC file such as a tsconfig.json with explanatory comments, or a JSON5 document, will stop at the first thing the standard does not allow.
NDJSON and JSON Lines fail for a different reason. A file with one object per line is several complete documents, not one, so the parser reads the first line successfully and then reports unexpected content at the start of the second. Wrapping the lines in square brackets with commas between them turns the file into a single array, which formats normally. For a file that only differs from strict JSON by its comments or a trailing comma, the JSON option on the Code Formatter page is the faster route: it goes through a source-code printer rather than the browser’s JSON parser, so it keeps comments where they are and accepts the loose syntax.
What a round trip through the parser changes
Formatting is a parse followed by a re-print, and a few things do not survive that unchanged. Numbers become double-precision floats, so a 20-digit identifier such as 12345678901234567890 comes back as 12345678901234567000; anything past sixteen or so significant digits loses its tail, 1.0 prints as 1, and a value too large to represent, such as 1e400, prints as null. If an identifier has to keep every digit, it needs to be a string in the payload — and if you only want to read a document without disturbing its numbers, the Code Formatter’s JSON option reprints the digits you gave it verbatim.
Duplicate keys are resolved silently, last one winning, so {"a": 1, "a": 2} comes back as {"a": 2} with no warning that anything was dropped. Key order is otherwise the order you wrote, with one exception inherited from the language: keys that look like non-negative whole numbers are hoisted to the front in ascending order, so an object keyed "2", "1", "x" comes back as 1, 2, x. There is no alphabetical sort option here, so if you are formatting two documents in order to compare them, sort the keys before pasting or the comparison will be full of moves. String escapes are normalised too: an escaped character written \u00e9 is printed as the letter é, and the optional \/ escape becomes a plain slash.
The JSON Path bar
Click anywhere in the formatted output and the bar underneath shows the path to that line — $.user.roles[0] — ready to paste into a query, a test assertion or a configuration file that addresses part of a response. Copy Path puts it on the clipboard. The path is worked out from the indentation of the printed text rather than from the parse tree, which has two consequences worth knowing. It needs the pretty-printed view: after you minify, the whole document is one line and the bar says so instead of guessing. And it follows the output pane only, so clicking in the input does nothing.
Size limits, deep nesting and privacy
No size cap is written into the tool; the ceiling is your browser. Parsing, printing and byte counting all run on the page’s main thread, so a document of a few megabytes formats with a visible pause and something in the tens of megabytes will lock the tab up for a while — both panes also have word wrap switched on, which is what makes very long single-line values expensive to draw. Depth has a separate limit: past a few thousand levels of nesting the recursive walk that produces the node count runs out of call stack, and you get a "maximum call stack size exceeded" message even though the output pane formatted the document correctly.
Everything else happens inside the tab. The parse, the printing, the byte count, the path lookup and the clipboard copy are all local, nothing is uploaded or written to browser storage, and reloading clears both panes. The one thing fetched from the network is the editor component, served from this site rather than a third-party CDN, so there is no second host to allow through a proxy and no outside party learns which pages you open. Pasting a production response with credentials in it is safe.
When a different tool fits better
To compare two responses, format both here and paste the results into the Diff Viewer; matching the indentation first is what stops the comparison from lighting up every line. For YAML, XML, SQL, HTML or a programming language, the Code Formatter covers nineteen languages and is also the page to use for JSON that carries comments or numbers you need printed exactly as written.
Validates as you type
Every keystroke is re-parsed. Valid input is reprinted on the right; invalid input puts the parser’s own message, with its line and column, under the toolbar while the last good result stays on screen.
Pretty print or minify
Indent with tabs or two, four, six or eight spaces, or strip every space and newline. The byte counter reads the output pane, so you can see precisely what your indentation costs.
Path for any line
Click a line in the formatted output and its path appears below the editors, ready to copy into a query or a test assertion.
Frequently Asked Questions
Is my JSON uploaded anywhere?
No. Parsing, printing, the byte count, the path lookup and the clipboard copy all run inside this tab, nothing is written to browser storage, and reloading clears both panes. The only network request the page makes is for the editor component, which is served from this site rather than a third-party CDN and carries none of your content.
Why does my file with comments in it fail to parse?
Because the standard has no comments and the browser parser that runs here implements the standard exactly. The same applies to trailing commas, single quotes, unquoted keys, hexadecimal numbers and the NaN and Infinity literals, which is why JSONC and JSON5 documents are rejected. Strip the comments, or open the file on the Code Formatter page and pick JSON there — that path uses a source-code printer that keeps comments in place.
Can I format a JSON Lines or NDJSON file?
Not directly. One object per line is several documents rather than one, so the parser reads the first line and then reports unexpected content at the start of the second. Wrap the lines in square brackets with commas between them and the file becomes a single array, which formats normally.
A long number came back different. Is that a bug?
No. Numbers are read as double-precision floats, so an identifier such as 12345678901234567890 comes back as 12345678901234567000 and a value too large to represent, such as 1e400, prints as null. Identifiers that must keep every digit belong in the payload as strings.
What happens to duplicate keys?
The last one wins and the others disappear without a warning, so an object written with "a" twice comes back with a single "a" holding the second value. If you suspect a payload of repeating a key, search the raw text instead — this page will not show you that.
Why has the JSON Path bar stopped updating?
It reads the indentation of the formatted text, so it needs the pretty-printed view. After you minify, the whole document is one line and the bar tells you to format it again. It also follows the output pane only — clicking in the input pane on the left does nothing.
The document looks fine but nothing parses. What else could it be?
A UTF-8 byte-order mark at the very start of the file: invisible in most editors, and rejected as an unexpected token at position 0. Re-save without it. The other common surprise is a smart quote pasted from a document or chat window in place of a straight double quote.