JSON validator
Not just valid or invalid. If it is not JSON, this says whether it is JSONC or JSON5, which rule it broke, and the smallest change that makes it JSON.
- SECURE
- NO UPLOADS
- NO SIGNUP
- BROWSER BASED
- FREE
- FOREVER.
Support us with a link or a share
A JSON validator that answers the question you actually have
Valid or invalid is a yes-or-no answer to a question almost nobody is asking. When a file gets rejected you already suspect it is not JSON — what you need to know is what it is instead, because that determines whether you edit the file or change the parser reading it. Those are completely different afternoons.
So this page gives a verdict rather than a light. It says this is JSON, or this is not JSON — it is JSONC, or this is not JSON — it is JSON5, or it says that not even the most permissive of the three can read the document to the end. Every deviation it finds is named, counted, located to a line and a character, shown with a pointer under the exact offender, matched to the rule it breaks, and paired with the smallest change that would make it plain JSON.
The three dialects, and why the distinction is practical
JSON is the strict one, specified in RFC 8259. Every key is a
double-quoted string, no comma may follow the last item, comments do not exist,
numbers are decimal and finite. JSON.parse in your browser implements
exactly this, which is why this page uses it as the authority: if the browser's own
parser accepts the text, the answer is JSON and nothing further needs saying.
JSONC is JSON with comments and trailing commas. It has no
specification — it is a convention, and different tools draw its edge in slightly
different places. This page draws it where Visual Studio Code draws it, because that is
where nearly everyone meets it: tsconfig.json, settings.json,
launch.json, devcontainer.json. Those files carry
// comments quite legally as far as the editor is concerned, and quite
illegally as far as any strict parser is concerned. That contested boundary is worth
stating out loud rather than pretending it is a standard.
JSON5 is a published specification and it is considerably more
relaxed: unquoted keys, single-quoted strings, hexadecimal numbers, numbers that start
or end with a decimal point, an explicit plus sign, NaN and
Infinity, and strings continued across lines with a trailing backslash.
The two supersets stack, and that is the useful part. Anything JSONC allows, JSON5 allows too — so the strictest deviation in your document decides what the whole document is. A configuration file full of comments is JSONC until one single unquoted key appears in it, at which point a comment-tolerant parser will still refuse it and you need a real JSON5 parser. One character changes the answer, and this page tells you which character it was.
What the verdict means for what you do next
If the answer is JSONC, the file is very probably fine and something is reading it
with the wrong parser. A build step that shells out to JSON.parse, a CI
script using jq, a language server pointed at a config it did not expect
to be commented — those all produce the same complaint, and stripping the comments out
of a checked-in tsconfig.json is the wrong fix. Point the reader at
jsonc-parser or an equivalent and the comments stay where their author
wanted them.
If the answer is JSON5, the file came from somewhere that was never emitting JSON in
the first place. Single quotes and unquoted keys are the fingerprints of a JavaScript
object literal that was copied out of a debugger or printed with
console.log rather than serialized —
converting the object literal to JSON is usually
faster than fixing it by hand. NaN and Infinity point
somewhere else entirely: Python's own json module emits both by default,
so a file produced by a standard library gets rejected by every strict reader
downstream. Passing allow_nan=False fixes it at the source instead of
three systems later.
If the answer is that none of the three can read it, the problem is structural rather than dialectal — a missing comma, an unclosed brace, a block comment that was never terminated and has swallowed the rest of the file. The page reports where the reading stopped and what it expected to find there. That is a genuinely different message from "this needs a more permissive parser", and conflating the two is what makes most validators unhelpful.
Why the verdict is not a tolerance switch
The obvious way to build this tool is a set of checkboxes: allow comments, allow trailing commas, allow unquoted keys. That design is worse than useless, because a validator that has been told to accept single-quoted strings is no longer validating JSON — it is validating whatever the person clicking the boxes already believed. The dialect is a property of the document, not a setting belonging to the reader, so there is nothing here to configure. You submit text; you get the answer.
It also means the findings are complete rather than filtered. The counts above the list cover every occurrence in the document even when only the first twelve are shown individually, because four hundred unquoted keys are not helped by four hundred identical paragraphs — but a summary that quietly under-reports would be a lie, and the page says which of the two it is doing.
Once you know, the neighbors take over
This page judges; it does not rewrite. When the verdict is JSON and you want it laid
out over lines, sorted, or minified back down,
the JSON formatter is the tool next door and keeps
long integer identifiers and duplicate keys intact while it works. If the document
turned out to be a base64 blob starting eyJ rather than JSON at all, and
it has two dots in it, the JWT decoder splits the segments
and reads the expiry as a date. If you are comparing two responses that ought to be
identical, a text diff of two consistently formatted copies
is the shorter route to the handful of values that actually changed. And when the
source is XML rather than JSON, the XML validator answers
the equivalent question for that format, where well-formed and valid are two separate
properties rather than one.
Your configuration files stay on your machine
Consider what gets pasted into a JSON validator: an API response captured while
debugging, a service account file, a webhook payload, a Kubernetes secret, a
settings.json containing internal hostnames. Those documents routinely
carry bearer tokens, access keys, email addresses and customer records, and pasting
them into whichever validator ranked first that morning is one of the quietest data
leaks in software work.
Nothing here is transmitted. The scan is JavaScript running in this tab, there is no upload endpoint on this site for it to reach, and you can confirm it in ten seconds: open your browser's network panel and then paste your document. No request appears, because there is nowhere for one to go. That also makes the page usable on a client's laptop under a client's acceptable-use policy, where outside formatter and beautifier sites are frequently named by category and blocked before you ever meet the bug.
Questions
Why does this JSON validator say my file is JSONC?
Because it is. JSONC is JSON with comments and trailing commas, and it is what VS Code accepts in tsconfig.json and settings.json. A file like that is not broken — it is written in a dialect the parser reading it does not accept. Knowing which of the two is true changes the fix completely: one is a text edit, the other is a parser choice.
What is the difference between JSONC and JSON5?
JSONC adds two things to JSON: comments and trailing commas. JSON5 adds those and then a great deal more — unquoted keys, single-quoted strings, hexadecimal numbers, leading and trailing decimal points, explicit plus signs, NaN and Infinity, and strings continued across lines with a backslash. The strictest thing in your document decides which one you need, so a single unquoted key turns a file full of comments from JSONC into JSON5.
Is the JSONC boundary official?
No, and that is worth saying plainly. JSON itself is a standard (RFC 8259) and JSON5 has a published specification, but JSONC is a convention rather than a specification, and different tools draw its edge in different places. This tool draws it where Visual Studio Code draws it, because that is where almost everyone meets the format: comments and trailing commas, and nothing else.
Can it tell me where the problem is?
Every finding carries a line, a character position, the line itself with a pointer under the exact character, the rule that was broken and the smallest change that fixes it. When even JSON5 cannot read the document, the blocker gets the same treatment — the position and what was expected there.
Does my JSON leave the browser?
No. The scan runs on your own machine and this site has no route the text could be sent along. That matters here more than for most formats: the JSON people need to check is usually an API response or a config file, which routinely contains access tokens, internal hostnames and customer records.