Skip to content
LocalOnly
JSON Tools

JSON with Comments: JSON vs JSONC vs JSON5 Explained

The same file opens cleanly in VS Code and is rejected by npm. The difference is which of three JSON dialects each tool reads.

Updated October 18, 20264 min readTool runs in your browser

Can JSON have comments? Strict JSON cannot, which is why a config file can open without complaint in VS Code and still stop a build with an error like Expected property name or '}' in JSON at position 4 (line 2 column 3). Position 4 is usually the first character of a comment.

Nothing is wrong with the file by its author's rules. It is written in a JSON dialect that allows comments, and the tool reading it expects strict JSON. This guide compares the three dialects that share the .json look, lists which common tools accept each, and shows how to convert to strict JSON when you need to. The JSON Validator checks strict JSON, which is what most parsers expect.

JSON vs JSONC vs JSON5 side by side

Here is one small config written in JSON with Comments. It has a line comment and two trailing commas:

config.jsonc
{
  // dev server port
  "port": 8080,
  "hosts": ["localhost",],
}
  • JSON (RFC 8259) allows none of that: keys and strings in double quotes, no comments, no trailing commas, and no Infinity or NaN.
  • JSONC is JSON plus // and /* */ comments, and most JSONC parsers also accept trailing commas. It started as the format of VS Code settings files, and Microsoft's jsonc-parser package is the common implementation.
  • JSON5 is a larger superset, specified at json5.org. On top of comments and trailing commas it allows single-quoted strings, unquoted keys, hexadecimal numbers, numbers such as .5 or 5., Infinity and NaN, and strings continued across lines.
Valid JSON5, invalid JSON
{
  unquoted: 'single quotes',
  hex: 0xFF,
  half: .5,
  limit: Infinity,
}

Which tools read which dialect

  • package.json is strict JSON. npm stops at the first comment with EJSONPARSE and the message package.json must be actual JSON, not just JavaScript.
  • tsconfig.json accepts comments and trailing commas, because TypeScript reads it with its own parser.
  • VS Code's settings.json, launch.json and other files it shows in JSON with Comments mode accept comments.
  • Babel reads .babelrc as JSON5.
  • JSON.parse, Python's json module and jq accept only strict JSON.

The error messages for the config above are worth recognising, because two of them do not mention comments at all:

JSON.parse   Expected property name or '}' in JSON at position 4 (line 2 column 3)
Python json  Expecting property name enclosed in double quotes: line 2 column 3 (char 4)
jq           jq: parse error: Invalid numeric literal at line 2, column 5

jq's message sends people looking for a broken number. It is the // of the comment, which jq tries to read as a literal value.

Converting JSONC or JSON5 to strict JSON

When a tool needs strict JSON, keep the comments in the source file and convert at build time. In Node, jsonc-parser handles comments and trailing commas:

convert.mjs
import { readFileSync, writeFileSync } from "node:fs";
import { parse } from "jsonc-parser";

const errors = [];
const config = parse(readFileSync("config.jsonc", "utf8"), errors, {
  allowTrailingComma: true,
});
if (errors.length > 0) throw new Error("config.jsonc is not valid JSONC");
writeFileSync("config.json", JSON.stringify(config, null, 2));

Check the errors array rather than the return value. Without allowTrailingComma, jsonc-parser still returns a usable object for the file above, but it records an error for each trailing comma, and a script that ignores the array will not notice.

For JSON5, the json5 package works the same way: JSON5.parse(text), then JSON.stringify. One value does not survive the trip. JSON has no Infinity or NaN, so JSON.stringify writes them as null, and limit: Infinity above becomes "limit": null.

Packages that only strip comments, such as strip-json-comments, are not always enough. Version 3, for example, removes the comments but leaves the trailing commas, so the result still fails JSON.parse.

Picking a format for a new config file

  • If programs write the file, or many different tools read it, use strict JSON. Every language reads it the same way.
  • If people edit it and your tools already understand JSONC, as TypeScript and VS Code do, JSONC adds comments without surprises.
  • If people edit it often and want unquoted keys and readable numbers, JSON5 is pleasant, but check that every tool that reads the file supports it.
  • Name the file .jsonc or .json5. A .json extension tells both people and tools to expect strict JSON, and VS Code recognises .jsonc as JSON with Comments.

Frequently asked questions

Command Palette

Search for a tool or command