JSON vs JSON5 vs JSONC: Which One Are You Actually Writing?
If your .json file has comments, trailing commas, or unquoted keys, it isn't actually JSON — and a strict parser will reject it. There are three dialects in common use today, and the file extension tells you nothing about which one you have. Here's how to tell, and which tool eats which.
The three dialects
Standard JSON (RFC 8259)
The strict spec. What JSON.parse() in your browser, json.loads() in Python, and almost every public API expects. The rules are deliberately rigid:
- Object keys must be double-quoted strings.
{ a: 1 }is invalid. - Strings use double quotes only.
'hello'is invalid. - No comments — neither
//nor/* */. - No trailing commas in arrays or objects.
[1, 2, 3,]is invalid. - No
NaN,Infinity, or-0as numeric literals. - No hexadecimal numbers —
0xFFis invalid.
JSON5
An informal extension that allows everything the strict spec forbids. The motivation is "JSON, but writeable by humans without the parser screaming at you." JSON5 features:
- Single or double quoted strings.
- Unquoted object keys (if they're valid identifiers).
//line comments and/* */block comments.- Trailing commas.
- Hex numbers, leading/trailing decimal points, plus signs,
NaN,Infinity. - Multi-line strings via line continuation.
JSON5 is its own format with its own libraries (json5 on npm, json5 in Python). Files are typically named .json5. It's used in some build tools and config files but is not interchangeable with strict JSON.
JSONC
"JSON with Comments." It's not a formal spec — it's a convention popularised by Microsoft for VS Code's config files. JSONC is approximately:
- Standard JSON, plus
//and/* */comments. - Trailing commas (in most JSONC parsers, including VS Code's).
- Otherwise the same as standard JSON — keys must be quoted, strings double-quoted.
JSONC is what TypeScript's tsconfig.json uses, what VS Code's settings.json uses, and what GitHub's .devcontainer.json uses. The files are named .json (not .jsonc), and that's where confusion starts: those files look like JSON, are named .json, and have comments. They're JSONC.
Quick comparison
| Feature | JSON | JSONC | JSON5 |
|---|---|---|---|
Comments (//, /* */) | ✗ | ✓ | ✓ |
| Trailing commas | ✗ | ✓ (most parsers) | ✓ |
| Unquoted keys | ✗ | ✗ | ✓ |
| Single-quoted strings | ✗ | ✗ | ✓ |
| Hex numbers, NaN, Infinity | ✗ | ✗ | ✓ |
| Standard file extension | .json | .json | .json5 |
Why your file fails the strict validator
If you paste content into our JSON formatter and get an error like Unexpected token / in JSON at position 47, the most common causes are:
- Comments. A line starting with
//or a block/* */means it's JSONC or JSON5, not JSON. - Trailing comma. The error position is usually right after the last item.
- Unquoted key. The error often says "Unexpected token in JSON at position X" where X is the start of an identifier.
- Single quotes. Look for
'instead of". - Trailing/leading content. A common one: a JS file that wraps JSON in an assignment (
const config = { ... };) is not JSON.
Which dialect should I write?
For data-on-the-wire: strict JSON, no exceptions
API responses, logging, queue messages, anything that crosses a network boundary or gets stored in a column where another system will read it. Strict JSON is universal; the relaxed dialects aren't. JSON.stringify(), Python's json.dumps(), Go's encoding/json — all produce strict JSON.
For human-edited config: JSONC if your tool accepts it, JSON5 if you need more flexibility
Tools that read tsconfig.json, settings.json, etc. accept JSONC. If you control the parser, JSONC is the cleanest choice — comments and trailing commas, no unquoted keys to confuse the eye. JSON5 is appropriate when the file is large, hand-written, and you'd reach for YAML or TOML otherwise.
Avoid: JSON5 in places that expect JSON
Don't put unquoted keys in a file consumed by a strict parser. The author who reads your file in three years won't know whether to use JSON.parse or json5.parse — they'll guess wrong, get an error, and spend 20 minutes figuring out it's JSON5 because the extension said .json.
How to convert between them
JSON5 → JSON: parse with the JSON5 library, then serialize with JSON.stringify. This drops comments and any unquoted keys.
// Node.js
const JSON5 = require('json5');
const data = JSON5.parse(fs.readFileSync('config.json5', 'utf-8'));
fs.writeFileSync('config.json', JSON.stringify(data, null, 2));
JSONC → JSON: same recipe; the jsonc-parser npm package will handle comments and trailing commas. Comments don't survive — JSON has nowhere to put them.
JSON → JSONC or JSON5: trivially, since they're supersets. Add comments by hand where they're useful.
Validate any of these in the browser
Our JSON formatter and validator uses strict JSON via JSON.parse. If you're working with a JSONC config file and want to check the underlying structure, strip the comments first or paste it into a JSONC-aware parser. For format conversions between JSON and YAML (which has its own commenting and structural conventions), our YAML/JSON converter handles both directions.