Why the spec excludes comments
Douglas Crockford, who specified JSON in the early 2000s, has explained the choice directly:
I removed comments from JSON because I saw people were using them to hold parsing directives, a practice which would have destroyed interoperability.
Two specific concerns:
- Interoperability. Every JSON parser would have to
implement comments identically. In practice they wouldn't — some
would treat
//as a line comment, others would require/* */, others might use#. - Pragma abuse. Once comments are allowed, tools
start putting metadata in them — magic strings like
// @version 2that change parser behavior. JSON stays predictable by not having anywhere to put metadata.
That tradeoff was right for an interchange format between programs. It's awkward when humans hand-edit JSON config files — which is why so many ecosystems have invented relaxed variants.
The variants, ranked by adoption
JSONC — JSON with Comments
Adds // line comments and /* */ block
comments. Optionally trailing commas. Used by:
- VS Code (
settings.json,keybindings.json) - TypeScript (
tsconfig.json) - Deno (
deno.jsonvia the Deno standard library)
Parsers: jsonc-parser (the official VS Code one) on npm.
JSON5
A bigger superset. Adds, on top of JSONC:
- Single-quoted strings
- Unquoted keys (when they're valid JS identifiers)
- Hex literals (
0x1F) - Leading
+on numbers,NaN,Infinity - Multi-line strings via
\continuation
Parsers: json5 on npm.
HJSON, JSONNET, RJSON, others
Niche variants exist but rarely appear outside specific projects. If you don't already have a strong reason, prefer JSONC for config and stay with strict JSON for wire formats.
Workarounds for strict JSON
If the consumer parses with strict JSON.parse and you
still need to leave a note, two patterns work:
The "//" key
{
"//": "Generated 2026-05-01 by deploy.sh — do not hand-edit",
"name": "my-app",
"version": "1.0.0"
}
Strict JSON; the consumer ignores the unknown key. Schema-validated
consumers may complain (additionalProperties: false),
in which case add // to the schema.
The sidecar file
Keep the comments in a separate config.notes.md next
to config.json. Doesn't pollute the data; survives any
parser; lets you write proper documentation rather than cramming
explanations into a string.
What about npm package.json?
npm rejects comments — package.json must be strict
JSON. The convention there is the //-key trick when
people really need a note, plus an npm-shrinkwrap.json
explanation file for context.
Frequent footgun: copying tsconfig.json (JSONC) snippets
into package.json with the comments still there
crashes npm install.
If you're hitting that error, our linter shows you the position.
Decision tree
- Wire format between programs? → Strict JSON. No variants.
- Config edited by humans, your parser? → JSONC if your tooling has a parser; otherwise plain JSON with sidecar documentation.
- Config edited by humans, third-party parser? → Whatever they accept. Often strict JSON; sometimes YAML or TOML which support comments natively.
- You need every feature including unquoted keys? → JSON5. Accept the larger compatibility cost.
Reference
- RFC 8259 — strict JSON, the current standard.
- microsoft/node-jsonc-parser — VS Code's official JSONC parser.
- JSON5 — full spec and reference parser.
FAQ
Can I just remove the comments before parsing?
You can, but be careful: a naive regex strip can mangle strings that contain // or /* */ inside them. If you control the producer, switch to JSONC and use a proper JSONC parser. If you don't, use a battle-tested library (jsonc-parser on npm) rather than rolling your own.
Why does VS Code's settings.json allow comments?
It's not strict JSON — it's JSONC (JSON with Comments). VS Code's parser strips comments before parsing. tsconfig.json uses the same convention. If you copy-paste from these files into a strict JSON context, the comments will break parsing.
What's the difference between JSONC and JSON5?
JSONC = JSON + comments + trailing commas (and that's it). JSON5 = JSONC + single quotes, unquoted keys, trailing commas in arrays/objects, leading + on numbers, hex literals, and more. JSON5 is closer to JS object literal syntax. JSONC is the safer choice for config files because it's a smaller superset.
Should config files just use YAML or TOML?
If you control the format and humans edit the file, yes — both YAML and TOML support comments natively. JSON is best as a wire format between programs. The fact that 'JSON for config' is so common is a quirk of history, not a design choice.
Is there a comment convention that works in strict JSON?
The most common workaround is a top-level key like "//" or "_comment" with the comment as the value. Parsers ignore it (it's just a key they don't expect), and the file remains strict JSON. Ugly, but works in any parser.