Skip to main content
ponderloop

JSON Formatter & Validator

Paste JSON and it is checked on the spot: if it is valid it is pretty-printed, and if not you get the message, the line and column and the offending line with a caret under it. The example is 129 bytes of compact JSON; pretty-printed with 2 spaces it is 182 bytes, and minified it is 129. Numbers keep every digit exactly as written, so 12345678901234567890 and 1.10 come out unchanged instead of being rounded. You can also minify, sort keys, find repeated keys, and copy or download the result. Your JSON never leaves the browser.

Updated Runs in your browser: nothing you enter is uploadedHow this tool works

Stays in your browser

Replace the example: paste or type JSON. It is checked as you type.

Your JSON is processed on this device and never uploaded. It is not saved either: reload the page and it is gone.

Options

Result

Valid JSON: an object

Size and structure

Before (UTF-8)
129 bytes
After (UTF-8)
182 bytes
Change
+53 bytes (+41.1%)
Depth
2
Objects
2
Arrays
1
Keys
8

What each option produces

The same input, {"b":[1,2],"a":{}}, with one option changed at a time (line breaks shown as ⏎).
OptionResultEffect
2 spaces{ ⏎ "b": [ ⏎ 1, ⏎ 2 ⏎ ], ⏎ "a": {} ⏎ }The default: one nesting level per two spaces.
4 spaces{ ⏎ "b": [ ⏎ 1, ⏎ 2 ⏎ ], ⏎ "a": {} ⏎ }One nesting level per four spaces.
Tab{ ⏎ "b": [ ⏎ 1, ⏎ 2 ⏎ ], ⏎ "a": {} ⏎ }One tab per nesting level.
Minify{"b":[1,2],"a":{}}All optional whitespace removed: the smallest valid text.
Sort keys{"a":{},"b":[1,2]}Keys in every object sorted by Unicode code unit order (shown minified); arrays keep their order.

Numbers are never rounded

Each value goes through the tool unchanged. Parsing and re-serializing it in JavaScript (the last column) alters most of them.
You typeThe tool outputsJSON.parse then JSON.stringify
123456789012345678901234567890123456789012345678901234567000
1.101.101.1
1E51E5100000
-0-00
0.10000000000000000555111512312578270.10000000000000000555111512312578270.1
"\u00e9\n""\u00e9\n""é\n"

Common mistakes and the message you get

Positions are 1-based; the column counts characters from the start of the line.
InputMessagePositionFix
{"a": 1,}Trailing comma before “}”. JSON does not allow a comma after the last property.line 1, column 8Remove the comma after the last property.
{"a": 1 "b": 2}Unexpected “"”. Expected “,” or “}”.line 1, column 9Add the missing comma between properties.
{'a': 1}Object keys must use double quotes, not single quotes.line 1, column 2Use double quotes around keys and strings.
{a: 1}Object keys must be strings in double quotes.line 1, column 2Quote the key: "a".
[1, 2, // two ⏎ 3]Comments are not allowed in standard JSON.line 1, column 8Delete the comment, or turn on lenient mode.
[01]Numbers cannot have leading zeros.line 1, column 3Write 1: JSON numbers have no leading zeros.
{"a": NaN}“NaN” is not valid JSON; numbers must be finite.line 1, column 7JSON has no NaN or Infinity; use null or a string.

How to format and validate JSON online

  1. Paste your JSON. Replace the example with your own text. It is checked as you type; for very large input, press Format instead.
  2. Read the verdict. A valid document shows its type, size and structure counts. An invalid one shows the message, the line and column, and the offending line with a caret.
  3. Choose the layout. Pick 2 spaces, 4 spaces, a tab or Minify, and turn on “Sort keys” to order every object’s keys A to Z.
  4. Fix problems. Use “Show in input” to jump to the error. If your data has comments or trailing commas, tick the lenient option to accept and remove them.
  5. Copy or download. Copy the result to the clipboard or download it as a .json file. Nothing is uploaded at any step.

Frequently asked questions

How do I validate JSON?
Paste it into the box. The tool parses it against the JSON grammar (RFC 8259) and either shows the formatted result or the first error with its line, column and a caret under the offending character. Only the first error is reported, because one mistake often causes several confusing follow-ups; fix it and the next one, if any, appears.
Why are comments and trailing commas errors?
Standard JSON has neither: a comment or a comma before a closing bracket makes the text invalid for most parsers, including JSON.parse. Files such as tsconfig.json and VS Code settings accept them because they are really JSON with comments (JSONC). Tick “Lenient” to accept both; they are removed from the output so the result is strict JSON.
Does it change my numbers?
No. Numbers are copied exactly as you wrote them, so 12345678901234567890 stays 12345678901234567890 (JavaScript would turn it into 12345678901234567000), and 1.10 keeps its trailing zero. The same goes for exponents such as 1E5 and for string escapes such as \u00e9.
What happens to duplicate keys?
JSON allows them in the grammar but says the behaviour is unpredictable, and most parsers silently keep the last one. The tool lists every repeated key with its path and position and keeps all copies in the output, so nothing is lost; sorting keys keeps repeated keys in their original order.
How does sorting keys work?
Every object, at every depth, gets its keys sorted by their decoded text in Unicode code unit order (so uppercase letters come before lowercase ones). The sort is stable and arrays are left in their original order, because order inside an array carries meaning.
Does it handle a file with a byte order mark?
Yes. A leading U+FEFF is removed, and the page says so. Many Windows tools add one, and JSON.parse rejects it.
How big a file can I paste?
About 5 MB works. Up to 500,000 characters the result updates a moment after you stop typing; above that the page waits for you to press Format so typing stays smooth. Nesting deeper than 500 levels is refused.
How is the size calculated?
In UTF-8 bytes, the encoding JSON files normally use, so a character such as é counts as 2 bytes and an emoji as 4. “Before” is your pasted text and “After” is the formatted result.
Is my JSON uploaded or saved?
No. Parsing and formatting happen in your browser, the text is not stored anywhere (not even in local storage) and it is gone when you close or reload the page. The only thing the site records, if you allow analytics, is that a button was used, never any of the text.

How it works

The text is read by a small recursive-descent parser written for this tool, following the grammar in RFC 8259 and ECMA-404: one value, objects with double-quoted keys, arrays, strings with only the defined escapes and no raw control characters, numbers of the form -?(0|[1-9][0-9]*)(.[0-9]+)?([eE][+-]?[0-9]+)?, and true, false and null. It does not use JSON.parse, so error positions and messages are the same in every browser, and it keeps each number and string as the original characters, so nothing is rounded or re-escaped. Line and column are counted in Unicode characters, with LF, CRLF and a lone CR each ending a line. Formatting prints the parsed tree again with the chosen indentation; sorting orders each object’s entries by decoded key in code unit order with a stable sort. Depth is the nesting of objects and arrays (a bare value is 0, [] is 1); keys are counted every time they appear, repeated or not. Sizes are UTF-8 byte counts of the text before and after.

Sources

All toolsHome & DIY calculators