JaguarVPN logo

JSON Formatter and Validator

Format, validate and inspect JSON — with an error that points at the character.

Output
{
  "name": "jaguar",
  "speed_kph": 80,
  "habitats": [
    "rainforest",
    "wetland"
  ],
  "conservation": {
    "status": "Near Threatened",
    "assessed": 2016
  },
  "nocturnal": null
}

Valid JSON

Size
145 B
Minified
145 B
Saved
0%
Keys
7
Objects
2
Max depth
3

The four mistakes

Almost every rejected document fails for one of the same handful of reasons, and all four are things JavaScript would have accepted. That is the trap: JSON looks like a JavaScript object literal and is a much stricter subset of one.

WrittenProblemCorrect
{"a": 1,}Trailing comma{"a": 1}
{'a': 1}Single quotes{"a": 1}
{a: 1}Unquoted key{"a": 1}
{"a": 1} // noteCommentRemove it

Two more that catch people less often but are harder to spot. NaN, Infinity and undefined are all valid JavaScript values and none of them is a JSON value — null or a string is the substitute. And a literal newline inside a string is invalid; it has to be the two characters \n.

How this validator reports errors

Worth explaining because it is the reason to use one formatter over another. The browser’s own JSON.parse is used for the success path, but not for describing failures: its message format is an implementation detail that has changed twice in recent V8 releases. The same broken document reports “Unexpected end of JSON input” on one Node version and “Expected ‘,’ or ‘}’ after property value at position 6” on another, and sometimes gives no position at all.

So when parsing fails, this page walks the grammar itself and reports the line, the column and the character it stopped at, with a caret underneath. The message you get does not depend on which browser you happen to be using.

The precision problem nobody warns you about

This one causes real bugs and is almost never mentioned. JSON numbers become JavaScript numbers, and JavaScript numbers are IEEE 754 doubles. Integers above 253 — roughly 9.007 quadrillion — cannot be represented exactly.

A 19-digit identifier of the kind Twitter, Discord and most Snowflake-style ID schemes produce will come back changed, silently, with no error anywhere. Paste {"id": 9007199254740993} into the formatter above and watch the last digit move.

The fix is on the producing side: send 64-bit identifiers as strings. Every API that has been bitten by this now does.

When to reach for something else

This page is for reading and fixing a document you have in front of you. Two adjacent jobs it is the wrong tool for:

  • Querying and transforming. jq on the command line, which also streams rather than loading everything into memory — the right answer for anything above a few megabytes.
  • Enforcing a shape. That is JSON Schema, and validating structure is a different question from validating syntax. A document can be perfectly well-formed and still be missing every field your API requires.

Related

If the JSON arrived Base64-encoded, decode it first. If it came out of a token, the JWT decoder splits and parses both segments for you. And if it is going into a URL, the URL encoder shows which of the three escaping rules you want.

JSON questions

Why does my JSON fail when it looks fine?

Four causes account for nearly all of it. A trailing comma before a closing bracket, which JavaScript accepts and JSON does not. Single quotes instead of double quotes. Comments, which JSON has no syntax for at all. And unquoted keys — {name: "x"} is valid JavaScript and invalid JSON. The validator above names which of these it found rather than restating the parser error.

Is it safe to paste production data in here?

Into this page, yes — it parses in your browser and there is no request that could carry it. You can confirm that by watching the network tab while you type. The general habit is worth keeping though: the JSON people debug is usually a real API response with real customer records in it, and plenty of online formatters post it to a server to do the work. Check before pasting, on any tool.

Can JSON have comments?

No. Douglas Crockford removed them deliberately, because people had started putting parsing directives in them. If you need comments in a config file, the usual answers are JSON5 or JSONC (what VS Code uses), or convention — a "_comment" key that consumers ignore. None of those are JSON, so a strict parser will still reject them.

What does "sort keys" do and why would I want it?

It reorders every object's keys alphabetically, recursively. JSON objects are unordered by specification, so two documents that differ only in key order are equivalent — but a text diff shows every line as changed. Sorting both before comparing collapses that to the differences that actually matter.

Is there a size limit?

Only your browser's. Parsing happens in the page, so a few megabytes is fine on a desktop and will make an older phone work for it. Very large documents are better handled with jq on the command line, which streams rather than holding the whole tree in memory.

Why is my large integer coming back wrong?

Because JSON numbers become JavaScript numbers, which are IEEE 754 doubles, and those lose precision above 2⁵³ — about 9.007 quadrillion. A 19-digit Twitter-style ID or a database bigint will come back subtly altered. This is not a bug in the formatter; it is why APIs that use 64-bit IDs send them as strings.

Last reviewed . Found something out of date? Tell us.