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.
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:
{
// 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
InfinityorNaN. - 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'sjsonc-parserpackage 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
.5or5.,InfinityandNaN, and strings continued across lines.
{
unquoted: 'single quotes',
hex: 0xFF,
half: .5,
limit: Infinity,
}Which tools read which dialect
package.jsonis strict JSON. npm stops at the first comment withEJSONPARSEand the messagepackage.json must be actual JSON, not just JavaScript.tsconfig.jsonaccepts comments and trailing commas, because TypeScript reads it with its own parser.- VS Code's
settings.json,launch.jsonand other files it shows in JSON with Comments mode accept comments. - Babel reads
.babelrcas JSON5. JSON.parse, Python'sjsonmodule 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 5jq'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:
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
.jsoncor.json5. A.jsonextension tells both people and tools to expect strict JSON, and VS Code recognises.jsoncas JSON with Comments.
Related tools
Pretty-print JSON with configurable indentation and instant validation.
Validate JSON against a JSON Schema using AJV.
Turn minified or tangled JSON into clean, readable, well-indented text.
Query JSON with JSONPath expressions and see live results.
Related guides
Two formatters can disagree about the same JSON file. Here is how a team picks one, applies it in every editor and before every commit, and makes CI enforce it.
Checking a request body against a JSON Schema replaces dozens of hand-written if statements. Here is a tested setup for Node and Python, and a 400 response that tells the client exactly what to fix.
Four ways to make JSON readable without leaving your terminal or browser, and the three edge cases where pretty printing changes the data.
Three query languages for JSON look alike and behave differently. Here are ten everyday queries in all three, with the results they actually return.