toolgarden.xyz
中文
JSONJSONCJSON5TypeScript

Why Can Some JSON Files Have Comments?

tsconfig.json, settings.json, and launch.json look like JSON, yet they accept comments. The reason is JSONC, not strict standard JSON.

ToolGarden tools prioritize browser-local processing, so files and text do not need to be uploaded to a server.

Published July 1, 2026Updated July 3, 20266 min readBy ToolGarden

If you have written TypeScript, this file probably looks very familiar:

{
  /* Visit https://aka.ms/tsconfig to read more about this file */
  "compilerOptions": {
    "target": "ES2022",
    "strict": true
  }
}

Wait...

Isn’t JSON supposed to forbid comments?

According to the JSON standard, examples like these are invalid:

// This is a single-line comment
{
  "name": "ChatGPT"
}
{
  /*
   This is a block comment
  */
  "name": "ChatGPT"
}

So why can configuration files such as tsconfig.json, settings.json, and launch.json use comments without any drama? Let’s unpack the reason.

Why Does JSON Not Allow Comments?

JSON, short for JavaScript Object Notation, was designed first as a data interchange format.

Simple, consistent, and easy to parse.

That is why the official JSON specification, RFC 8259, does not include comments. Standard JSON only allows these values:

  • Object
  • Array
  • String
  • Number
  • Boolean
  • null

Everything else, including comments, trailing commas, and single-quoted strings, is outside the standard.

A standard JSON parser will reject a file like this:

{
  // User name
  "name": "Tom",
}

Why Are Comments Useful Anyway?

JSON does not support comments, but configuration files often need them badly.

Without comments, a config may look like this:

{
  "strict": true,
  "module": "NodeNext",
  "target": "ES2022"
}

For someone new to the project, strict may be unclear, and target: ES2022 may raise more questions than it answers.

With comments, the same intent becomes much easier to read:

{
  // Enable strict mode. Keeping this true is recommended.
  "strict": true,
  // Emit ES2022 code.
  "target": "ES2022"
}

Comments help configuration files in a few practical ways:

  • They reduce the learning curve because options can explain themselves.
  • They help teams communicate why a setting exists, not just what the value is.
  • They preserve maintenance context for unusual project choices.
  • They improve the editing experience because many IDEs display and preserve those notes.

So while JSON itself does not support comments, real-world configuration often benefits from them.

Why Can tsconfig.json Use Comments?

The answer is simple: it is not strict JSON. TypeScript does not feed tsconfig.json directly to a standard JSON parser. It uses an extended format called JSONC, short for JSON with Comments.

JSONC adds a small set of features on top of JSON:

  • Single-line comments with //
  • Block comments with /* */

For example:

{
  // Output target
  "target": "ES2022",
  /*
    Whether strict mode is enabled
  */
  "strict": true
}

The TypeScript compiler removes the comments first, then parses the remaining text like ordinary JSON.

So even though the filename is tsconfig.json, its contents are closer to tsconfig.jsonc. The .json extension remains mostly for ecosystem compatibility.

JSONC Is Not the Only Extension: Meet JSON5

The two most common JSON extensions you will see are JSONC and JSON5.

1. JSONC

JSONC is intentionally conservative. It supports line comments and block comments while staying very close to standard JSON. Trailing commas are not encouraged by the core format, even though some implementations may tolerate them.

{
  // User name
  "name": "Tom"
}

Typical JSONC use cases include TypeScript tsconfig.json, VS Code settings.json, launch.json, and VS Code extension configuration files.

2. JSON5

JSON5 goes further. In addition to comments, it supports single quotes, trailing commas, unquoted object keys, hexadecimal numbers, Infinity, and NaN.

{
  // User
  name: 'Tom',
  age: 18,
  skills: [
    'JS',
    'TS',
  ],
}

At that point, it starts to feel much closer to a JavaScript object literal. Many frontend tools support JSON5, including Babel, parts of the Next.js ecosystem, and various Node.js toolchains.

Which Tools Support JSONC?

JSONC support is common in modern developer tooling. If you work in frontend development, you will probably touch JSONC sooner or later.

ToolJSONC support
TypeScriptYes
VS CodeYes
Visual StudioYes
Azure configurationYes
ESLint, in some configsYes
Monaco EditorYes

How Do You Convert JSONC to Standard JSON?

If you need to send JSONC to an API, database, or any program that only accepts standard JSON, you need to strip comments first.

Option 1: Use an npm package

Microsoft’s jsonc-parser package can handle JSONC, and strip-json-comments can remove comments before you parse or serialize the result.

npm install jsonc-parser
npm install strip-json-comments

Option 2: Use an online tool

If you only need to clean a config file occasionally, an online tool is often faster than adding another dependency.

Summary

When people first see comments inside tsconfig.json, it can look strange. The key idea is simple: standard JSON does not allow comments; TypeScript uses JSONC; JSONC makes configuration files easier to read and maintain; JSON5 adds even more JavaScript-style syntax.

For developers, comments in configuration files have become normal across modern toolchains. Understanding JSON, JSONC, and JSON5 helps you choose the right format for each situation.

The next time you see a comment inside tsconfig.json, you do not need to wonder why. It is not strict JSON. It is JSONC.

Frequently asked questions

Q.If JSONC already allows comments, why does JSON5 exist separately?

JSONC only adds comments and trailing commas to standard JSON — everything else stays strict. JSON5 goes much further: single-quoted strings, unquoted object keys (like JavaScript), multi-line strings, hex numbers, +/-Infinity, and NaN. It is essentially a static JavaScript object literal. JSONC targets maintainable config files; JSON5 targets hand-authored data. Different tools pick different variants: VS Code and TypeScript use JSONC, some scripting engines and data pipelines default to JSON5.

Q.Will JSON.parse fail on tsconfig.json?

Yes, in most cases. JSON.parse strictly implements RFC 8259 and throws SyntaxError the moment it sees a comment or trailing comma. tsconfig.json is JSONC internally, which requires TypeScript's own parser (ts.parseConfigFileTextToJson) or the jsonc-parser library. To read commented configs from your own Node.js code, either strip comments first with strip-json-comments or jsonc-parser and then call JSON.parse, or use a JSON5 library that handles a superset of these relaxations directly in one step.

Q.Can package.json have comments? Why is it different from tsconfig.json?

No. package.json is parsed by npm, yarn, pnpm, and countless other tools, all using strict JSON parsers. A single // or /* */ can break `npm install` for the entire project. tsconfig.json is read exclusively by TypeScript, which chose to use a JSONC parser. package.json is an ecosystem standard — you cannot force every tool to relax its parser. Add explanations via extra fields like "description" or a sibling README, not inline comments.

Q.What do I lose when converting JSONC to standard JSON?

Only comments and formatting details (indentation, blank lines, trailing commas). All data structures and values are preserved exactly. The resulting JSON is portable to any RFC 8259 parser and safe to send over the wire. The downside is one-way: intent captured in comments disappears, leaving future maintainers to guess. Best practice is to keep the JSONC file as the human source of truth and generate a clean JSON build artifact for strict consumers.

Q.Why can't API responses use JSON with comments?

APIs cross language and platform boundaries. A Go server, an iOS Swift client, an Android Kotlin client, and Nginx or an API gateway in between all rely on strict RFC 8259 parsers — comments would break the entire chain. Comments also leak internal reasoning and history, which is a maintenance and sometimes security concern. Config files are for humans and can be relaxed; API payloads are for machines and must be strict. Document API fields in your docs, not in the payload.