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:

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:

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:

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

FeatureJSONJSONCJSON5
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:

  1. Comments. A line starting with // or a block /* */ means it's JSONC or JSON5, not JSON.
  2. Trailing comma. The error position is usually right after the last item.
  3. Unquoted key. The error often says "Unexpected token in JSON at position X" where X is the start of an identifier.
  4. Single quotes. Look for ' instead of ".
  5. 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.