Short answer: No, standard JSON does not allow comments. A
//or/* */anywhere in the file makes it invalid. If you need comments, use JSONC or JSON5 where your tooling supports it, add a"_comment"key, or strip comments before parsing.
You add a quick note to a config file, save it, and the app refuses to start:
SyntaxError: Unexpected token '/', "{\n // data"... is not valid JSON
Every developer hits this once. JSON looks like JavaScript, JavaScript has comments, so surely JSON does too? It does not, and the reason is deliberate. This article explains why, shows the exact failure you get in each language, and then walks through five workarounds ranked from safest to most invasive.
Repair a copy of the failing payload with the JSON Fixer, then review the changes before using the result.
Why JSON Has No Comments
Early drafts of JSON did allow comments. Douglas Crockford removed them in the early 2000s after seeing people use them to carry parsing directives, the kind of thing that turns a data format into a configuration language that every parser has to agree on. His stated goal was interoperability: a format small enough that there could be no dialects.
The specification, RFC 8259, has stuck with that decision. The grammar defines whitespace as exactly four characters (space, tab, line feed, carriage return) and nothing else. There is simply no production rule for a comment, so a compliant parser must reject one.
What Happens When You Try
The error message changes by language, but the outcome is the same.
{
// the API key for staging
"apiKey": "sk-test-123"
}
- JavaScript:
SyntaxError: Unexpected token '/' - Python:
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes - Go:
invalid character '/' looking for beginning of object key string - Java (Jackson):
Unexpected character ('/')unlessALLOW_COMMENTSis enabled
If you are staring at one of these right now, paste the file into JSON Prettifier and click Validate. It reports the exact line, which is usually the first comment. Our guide to JSON parse errors covers the other causes of that message.
5 Ways to Add Comments to JSON
1. Use JSONC where your tool already supports it
JSONC stands for "JSON with Comments". It is standard JSON plus // line comments, /* */ block comments, and trailing commas. You already use it without noticing: VS Code's settings.json, TypeScript's tsconfig.json, and ESLint's .eslintrc.json are all parsed as JSONC.
{
// Only applies to the "src" folder
"compilerOptions": {
"strict": true, /* turn off while migrating */
"target": "ES2022"
}
}
When it works: the file is read by a tool that documents JSONC support. When it fails: the moment any other program reads the same file with a standard parser. If you want to read JSONC yourself, Microsoft publishes the jsonc-parser npm package, the same one VS Code uses. Naming the file .jsonc makes the intent clear to teammates and editors.
2. Use JSON5 for hand-edited config
JSON5 is a bigger superset aimed at humans typing config by hand. On top of comments it allows unquoted keys, single quotes, multi-line strings, hex numbers, and trailing commas.
{
// JSON5 example
name: 'my-service',
retries: 0x3,
hosts: [
'a.internal',
'b.internal', // trailing comma is fine
],
}
import JSON5 from "json5";
const config = JSON5.parse(fs.readFileSync("config.json5", "utf8"));
Babel, Chromium, and several Rust tools accept JSON5 config. It is a good fit when one codebase owns both the file and the parser. It is a poor fit for anything that leaves your repo, because the consumer would need the json5 package too.
3. Add a "_comment" key
This is the only approach that stays 100% valid JSON. You store the note as data under a key the application ignores:
{
"_comment": "Rotate this key every 90 days. Last rotated 2026-07-01.",
"apiKey": "sk-test-123",
"timeoutMs": 5000,
"timeoutMs_comment": "Raised from 3000 after the June incident"
}
Pick one convention and stick to it. _comment, // as a key, and "#" are all common. Two rules keep it safe: the consuming code must tolerate unknown keys, and JSON Schema validators must not use additionalProperties: false on that object, or the comment itself fails validation. If your schema is strict, read our JSON Schema guide before adding comment keys.
Also remember that a duplicate key is undefined behavior in JSON. Two "_comment" keys at the same level means most parsers keep only the last one.
4. Keep comments in source, strip them at build time
If your JSON is generated or bundled anyway, write comments freely and remove them before the file is consumed. The strip-json-comments package handles this correctly, meaning it will not touch a // inside a URL string:
import fs from "node:fs";
import stripJsonComments from "strip-json-comments";
const raw = fs.readFileSync("config.jsonc", "utf8");
const config = JSON.parse(stripJsonComments(raw));
Avoid the tempting one-line regex. raw.replace(/\/\/.*$/gm, "") will destroy "https://example.com" and everything after the double slash. Comment stripping needs a real tokenizer.
5. Switch formats for config you fully control
Sometimes the honest answer is that JSON is the wrong format for a hand-edited file. YAML and TOML both support comments natively, and most config loaders accept them. The trade-off is a new set of parsing rules; YAML in particular has its own surprises, which we cover in JSON vs YAML for config files. Keep JSON for data that crosses a network boundary and consider YAML or TOML for files humans edit daily.
Which Workaround Should You Pick?
| Approach | Real comments? | Best for | Main risk |
|---|---|---|---|
| JSONC (JSON with Comments) | Yes (// and /* */) | Config files read by VS Code, TypeScript, ESLint | Not valid for standard parsers |
| JSON5 | Yes, plus unquoted keys, trailing commas | Hand-edited config in JS projects | Needs json5 parser on every consumer |
| "_comment" key | Simulated via data key | APIs, fixtures, any strict-JSON setting | Comment ships with data; must be ignored by code |
| Strip comments at build time | Yes, in source only | Build pipelines, bundlers | Extra build step; source and output differ |
| YAML or TOML instead | Yes, natively | Human-edited config when you control the format | Different parser, different gotchas |
A simple decision rule: if the file never leaves a tool that documents JSONC or JSON5 support, use that. If the file is read by anything else, use a comment key or keep notes outside the file in a README or commit message.
Places Where Comments Already Work
These files look like JSON but are parsed with a comment-tolerant reader:
- VS Code:
settings.json,keybindings.json,launch.json,tasks.json - TypeScript:
tsconfig.jsonandjsconfig.json - ESLint:
.eslintrc.json(legacy config) - Deno:
deno.jsonanddeno.jsonc - Jackson (Java) with
JsonReadFeature.ALLOW_JAVA_COMMENTSenabled
And the notable one that does not: package.json. npm uses a strict parser. The accepted convention there is a top-level "//" key, which npm explicitly ignores.
Common Mistakes
- Assuming a formatter will keep your comments. Most JSON formatters, including ours, validate first and reject comments. Format the stripped version, or use an editor-level JSONC formatter.
- Committing a
.jsonfile that is really JSONC. Rename it to.jsoncso CI, linters, and new teammates know what to expect. - Putting secrets in comments. A comment key is data. It ends up in API responses, logs, and browser bundles like any other field. See JSON security best practices.
- Leaving a trailing comma after the last comment line. Still invalid in plain JSON. Our trailing comma fix covers it.
Before shipping hand-edited settings, review these seven JSON config file mistakes, including parser mismatches, secrets, override rules, and validation of the final effective configuration.