Skip to main content
Fundamentals · 7 min read

Can JSON Have Comments? What to Use Instead

No, and the reason is more interesting than it sounds. What breaks, what JSONC and JSON5 actually change, and the one convention that works in plain JSON today.

Short answer: no. Neither // nor /* */ is valid JSON, and a conforming parser rejects both:

JSON.parse('{"a":1} // note')
// Unexpected non-whitespace character after JSON at position 8

JSON.parse('{/* x */ "a":1}')
// Expected property name or '}' in JSON at position 1

The long answer is worth a few minutes, because the reason comments were removed explains a lot about why JSON looks the way it does — and because there are three workable alternatives depending on who reads the file.

Why they were taken out

Early JSON did allow comments. Douglas Crockford removed them, and his stated reason was not that they complicated the grammar. It was that people had started using them to carry parsing directives — instructions to particular tools, smuggled into a format whose entire value proposition was that every parser agrees on what a document means.

Once a comment can change behaviour, two parsers can read the same bytes differently, and interoperability — the only real reason to choose JSON over anything else — is gone. Removing comments removed the temptation.

Whether you find that convincing probably depends on how many tsconfig.json files you have had to explain to someone. But it is a design decision with a rationale, not an oversight.

Where you have seen comments in JSON anyway

Plenty of files named .json are not JSON. tsconfig.json, .eslintrc.json, VS Code's settings.json and launch.json are JSONC — JSON with Comments — which is a distinct dialect that the tools reading them implement themselves.

DialectAddsRead by
JSONnothing — the baselineEverything.
JSONCLine and block comments, trailing commasVS Code, the TypeScript compiler, and tools that opt in.
JSON5Comments, trailing commas, unquoted keys, single quotes, hex, leading/trailing decimal points, Infinity and NaN, multi-line stringsOnly where a JSON5 parser is installed.

The convention that works in plain JSON

If the file must stay valid JSON, use a key. Keys are data, so this parses everywhere:

{
  "_comment": "Rate limit is per API key, not per IP. Raising it needs an infra ticket.",
  "rateLimit": 100,

  "retries": {
    "_comment": "3 is deliberate — the upstream times out at 30s and our gateway at 110s.",
    "count": 3,
    "backoffMs": 500
  }
}

It is not elegant. It costs bytes, it shows up in your types, and a consumer that rejects unknown properties will complain. But it is valid, it survives every parser, and it puts the explanation next to the thing it explains — which is the entire point of a comment.

Pick one prefix and keep to it. _comment, // and $comment are all in use; $comment is the one JSON Schema standardised, so it is the safest choice inside schema documents specifically.

The other three options

Use a format that has comments

If a human maintains the file, JSON may simply be the wrong format. YAML has comments, TOML has comments, and both were designed for configuration rather than for data interchange. Converting a config to YAML and generating the JSON from it as a build step gives you comments without asking any consumer to change.

Strip comments in the build

Keep a commented source file — config.jsonc — and emit plain JSON. Being explicit in the extension is the important part: it tells the next person, and every tool, which dialect they are holding.

Put the explanation where it belongs

Often the comment is not about the value but about the decision behind it, and a line in the README or the commit message serves better than a key nobody reads. "Why is this 3?" is answered best by git blame, if the commit message was written with that in mind.

If you just need to parse a file that has comments

Paste it into the validator and it will point at the comment and tell you plainly that JSON has no comment syntax, with the line and column. From there you can strip them by hand for a one-off, or reach for a JSONC-aware formatter such as Prettier if this is a file you maintain.

Worth knowing: the formatter and every other tool here use a strict parser deliberately. A tool that quietly accepted comments would tell you your file is fine right up until the moment something else rejects it.