Skip to main content

Comparison · Validators

JSON vs JSON5: What Validators Accept (and What APIs Will Reject)

Updated 2026-09-01 · 7 min read

JSON5 exists because humans wanted comments in config files and trailing commas in diffs. RFC 8259 exists because interchange needs a tiny grammar that JSON.parse and every other stack agree on. Putting both documents in the same textarea is how a frontend config that “validates” never survives the first POST to an API.

RFC 8259 JSON vs JSON5 on DevOkk validators (September 2026)

Last reviewed September 2026. Recheck both sites before you treat a cell as current.

ConstructJSON validator (RFC 8259)JSON5 validator

Default sample

{"ok":true} passes

{a:1,} passes

Trailing comma

Invalid

Valid

Unquoted keys

Invalid

Valid

Single-quoted strings

Invalid

Valid

Comments

Invalid

Valid

Hex numbers

Invalid

Valid

Infinity / NaN

Invalid

Valid in JSON5; stringify to JSON may become null

Typical API body

This is the contract

Will be rejected unless the server opted into JSON5

DevOkk therefore has two pages. JSON Validator is strict JSON. Default {"ok":true} passes; {"ok":true,} fails. JSON5 Validator uses JSON5.parse. Default {a:1,} passes as JSON5 and is shown as illegal JSON. That disagreement is the product. It is not a bug in either parser.

Schema is a third axis: A JSON validator is not JSON Schema. Pretty-print is JSON Formatter. JSONLint comparison: JSONLint vs DevOkk JSON Formatter.

What JSON5 adds that JSON forbids

The usual teaching list:

  • Unquoted keys that are valid identifiers: {a:1}
  • Trailing commas in objects and arrays
  • Single-quoted strings
  • Line and block comments
  • Hexadecimal numbers
  • Leading decimal points, extra whitespace in places JSON is picky
  • Infinity, -Infinity, NaN

Each of those is a landmine for JSON.parse. A trailing comma is the one that shows up in copied JavaScript objects. Unquoted keys are the one that shows up in hand-typed fixtures. Comments are the one that shows up in “JSON” files that were always JSONC or JSON5.

If your consumer is JSON.parse in a browser or json.loads in Python (without a JSON5 library), you need the left column of the table. If your consumer is a bundler config that documents JSON5, the right column is the honest check.

JSONC is not a free upgrade to JSON5

VS Code’s JSONC allows comments and trailing commas in some JSON-shaped files. It is not the full JSON5 grammar. A file with unquoted keys may fail JSONC and pass JSON5. A file with only comments may pass a JSONC-aware editor and still fail RFC 8259. Name the dialect your tool actually implements. DevOkk’s JSON5 page is JSON5. DevOkk’s JSON page is RFC 8259. There is no silent “JSONC mode.”

Infinity, NaN, and the trip back to JSON

JSON5 can parse Infinity. JSON.stringify(Infinity) is null. If you validate as JSON5, then stringify to send to an API, you did not send infinity. You sent null. That is a value change, not a pretty-print. Hex numbers similarly become decimal JSON numbers only after a conversion step you have to look at.

The JSON5 validator does not eval. Parsing is not execution. It still is not a sandbox for untrusted documents you do not understand; it is a parser.

Worked example: one object, two results

Document:

{
  // feature flag
  a: 1,
}
  • JSON validator: invalid (comment, unquoted key, trailing comma - the first error the engine reports is enough).
  • JSON5 validator: valid JSON5.
  • JSON.parse in the console: exception.
  • After a repair-to-JSON step you might get {"a":1} with the comment gone.

If the file must stay JSON5, stop after the JSON5 validator. If the file must travel as an HTTP body, emit strict JSON and re-check on the JSON validator.

Hex, leading dots, and the config files that were never APIs

{n: 0xFF} is JSON5. It is not JSON. After conversion you should see 255 as a JSON number if you stringify through a JSON5 parse. Confirm the output; do not assume hex survived.

{.5}-style leading decimals are a JSON5 convenience. RFC 8259 wants 0.5. A test fixture copied from a README that used JSON5 will fail CI’s JSON.parse.

tsconfig.json in the wild is often JSONC (comments, trailing commas), not full JSON5. package.json is JSON. .babelrc stories differ by era. Read the tool’s docs. Then pick JSON Validator or JSON5 Validator or a YAML parser. Guessing is how Friday breaks.

Repair versus validate-as-JSON5

Repair is for “this was supposed to be JSON and a human made a mess.” JSON5 validation is for “this is supposed to be JSON5.” Using repair on a JSON5 config can strip comments you wanted to keep. Using JSON5 validation on an API fixture can bless a document the server will 400.

Multiline strings and JSON5’s extra whitespace

JSON5’s extra whitespace and comment rules make diffs nicer in humans’ configs. They also make “byte-identical to the API example” false. If a golden file is JSON5 and production strips comments, your tests must parse with the same dialect the code uses. Mixing JSON.parse in tests with JSON5 on disk is a green-local, red-CI classic.

Single-quoted strings with escaped quotes are legal JSON5 and illegal JSON. A linter that only knows RFC 8259 will yell. That is the linter doing the job.

Why both results belong on the JSON5 page

The JSON5 tool showing “valid JSON5, invalid JSON” is the teaching output. If it only said valid, you would ship {a:1,} at an API. If it only said invalid, you would “fix” a JSON5 config that was never supposed to be RFC 8259. Keep the dual result. Then pick a consumer.

A minifier for JSON will remove whitespace and must not emit comments. Running a JSON minifier on a JSON5 file is a dialect change. JSON Minifier is for JSON. Do not treat minified JSON5 as a standard.

Trailing commas in arrays versus objects

JSON5 allows [1,2,] and {a:1,}. RFC 8259 allows neither. Pretty-printers in JS ecosystems emit the comma because git diffs are kinder. Your Go json.Unmarshal does not care about git diffs. Dual-validate the same paste: JSON5 green plus JSON red means you are holding a config dialect, not an HTTP body.

A single trailing comma after the last element is the whole incident in half of “but Prettier said it was fine” tickets. Prettier, ESLint jsonc/*, and DevOkk each implement a dialect. If they disagree, one is set to JSON and another to JSON5 or JSONC. That is a settings ticket, not a mysterious RFC. Match the parser to the file, then match the validator page to the parser.

YAML is another superset-shaped trap

YAML can look like JSON and accept more. YAML Validator is the YAML parser. Do not run YAML through JSON5.parse and call it a day. Convert on YAML to JSON when the destination is JSON, then syntax-check JSON.

undefined, functions, and the objects you copied from a console

JSON.stringify drops undefined in objects and turns undefined array slots into null. JSON5 is not eval of a JS object literal with methods. A paste that includes function () {} fails both validators. Copy JSON.stringify output when you meant JSON. Copy a JSON5 file when you meant JSON5. Copy a Chrome console object dump when you like pain.

JSON5’s identifier keys cannot be arbitrary strings with spaces unless you quote them. { "a b": 1 } is JSON (and JSON5). { a b: 1 } is neither.

Plus signs, implicit octal, and other “looks like JS” traps

JSON5 is not the full JavaScript expression grammar. +1 as a number may be accepted in JSON5 depending on the parser; it is not JSON. Do not assume every Chrome console trick is JSON5. If the JSON5 validator rejects it, believe the parser. If it accepts it and JSON.parse does not, you still cannot ship it as an API body.

A file named .json on disk that contains comments is often JSONC. Rename it in your head. CI that runs JSON.parse on every *.json will fail. That is CI protecting RFC 8259, not a vendetta against comments.

JSON5 also allows extra Unicode in comments that JSON never had a place for. Those comments will not survive a round-trip through JSON.parse. If the comment was the only documentation of a magic number, the API body will not carry it. Keep the JSON5 file in source control and emit JSON at the boundary.

OpenAPI, package.json, and the filename lie

OpenAPI documents are often YAML on disk but JSON in memory. A CI step that only runs JSON Validator on exported .json artifacts is correct. A step that runs it on a hand-edited openapi.yaml is not - use YAML Validator first, then convert. package.json must be strict JSON: no comments, no trailing commas. tsconfig.json in many repos is JSONC. The extension is a hint, not a parser. When in doubt, paste into both validators and read which one fails. A green JSON5 result with a red JSON result on the same text is the intended teaching moment: you are holding a config dialect, not an API body. Ship strict JSON at the boundary even if authors prefer comments in source.

Privacy

Both validators parse locally. Config files still contain secrets. Thirty-day localStorage drafts on a shared laptop are a leak. Clear them.

The dialect your API will reject

Open JSON Validator when the next consumer is RFC 8259. Open JSON5 Validator when the file is actually JSON5 and you want that grammar. Open JSON Formatter for indentation of JSON, not as a way to hide a trailing comma. The dialect is a contract. A validator that accepts more than the consumer is how production discovers the comma on Friday.

Frequently asked questions

What is JSON5?

A superset of JSON that allows comments, unquoted keys, trailing commas, single quotes, hexadecimal numbers, and extra whitespace. The default {a:1,} on JSON5 Validator is legal JSON5 and illegal JSON.

Will a JSON5 document work in JSON.parse?

Often no. That is why the JSON5 page shows both results. APIs that require RFC 8259 still need strict JSON. Pretty-print strict JSON on JSON Formatter after you convert.

Does the JSON5 validator execute the document?

No. It only parses. There is no eval. Infinity and NaN are allowed in JSON5; JSON.stringify will turn them into null if you convert.

Is JSON5 the same as JSONC or JSON with comments?

No. JSONC is a VS Code-ish comments-in-JSON dialect. JSON5 is a specified superset with more than comments. Do not assume a ‘JSON with comments’ file is JSON5 until a JSON5 parser accepts it.

When should I use JSON repair instead?

Repair tries to emit strict JSON from messy text. Use JSON5 validation when you intend to keep the JSON5 dialect. Use JSON Validator when the consumer is RFC 8259.

Does parsing upload my text?

No. Both validators run locally. Drafts stay up to 30 days in this browser. Do not paste production secrets.

More reading that links back to the same tools and workflows.