jsonJSONCJSON5configcomments

JSON Has No Comments — Here's What to Use Instead

·6 min read

Why JSON Has No Comments

JSON was designed by Douglas Crockford in 2001 as a minimal data-interchange format. Comments were deliberately excluded. Crockford's reasoning: he saw developers using comments in JSON config files to add parser directives — "parse this differently" — which turned comments into a second channel for instructions. Removing comments kept the format clean and unambiguous.

The result is that JSON is a data format, not a config format. But developers use it for config anyway, which is why the lack of comments is felt every day.

What Happens If You Add Comments Anyway?

json
{
  // This is a database URL
  "db": "postgres://localhost/myapp",
  "port": 3000
}

Every standard JSON parser throws a syntax error. JSON.parse() in JavaScript, Python's json.loads(), and Go's json.Unmarshal() all reject this immediately.

Option 1: Use a "_comment" Key

The most portable workaround — works with any JSON parser, no tooling required:

json
{
  "_comment": "Database connection config — use env vars in production",
  "db": "postgres://localhost/myapp",
  "port": 3000
}

Pros: Valid JSON, works everywhere. Cons: It's a data field, not a real comment — it shows up in parsed output. Use a consistent key name and strip it programmatically if needed.

Option 2: JSONC (JSON with Comments)

JSONC is a superset of JSON used by VS Code for all its config files (settings.json, launch.json, tasks.json, extensions.json). It adds single-line and multi-line comments:

json
// tsconfig.json supports JSONC
{
  "compilerOptions": {
    // Enable strict null checks
    "strict": true,
    /* Path aliases for cleaner imports */
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

Where JSONC is used: VS Code configs (.vscode/settings.json), some Azure and Microsoft tooling.

Parsing JSONC in Node.js:

javascript
import { parse } from "jsonc-parser";

const config = parse(`
  {
    // Hello
    "port": 3000
  }
`);
console.log(config.port); // 3000

Option 3: JSON5

JSON5 is a more ambitious superset that adds multiple quality-of-life improvements alongside comments:

json5
{
  // Single-line comment
  /* Multi-line
     comment */
  name: "Ravi",           // Unquoted keys
  message: "Hello
  World",                 // Multi-line strings
  hex: 0xDECAF,           // Hex numbers
  trailing: "comma",      // Trailing commas allowed
}

Where JSON5 is used: Babel config (babel.config.json5), some bundlers, and projects that want human-friendly config files.

Parsing JSON5:

javascript
import JSON5 from "json5";
const config = JSON5.parse(fs.readFileSync("config.json5", "utf8"));

Option 4: Switch to YAML or TOML for Config

If you're using JSON purely for configuration (not data interchange), YAML and TOML both have native comment support:

yaml
# Database connection — use env vars in production
db: postgres://localhost/myapp
port: 3000
toml
# Database connection
db = "postgres://localhost/myapp"
port = 3000

Both are well-supported in every major language. YAML is dominant in infrastructure (Docker, Kubernetes, GitHub Actions). TOML is favoured in Rust (Cargo.toml) and Python (pyproject.toml).

The Right Choice

  • API data exchange? Use plain JSON. Comments don't belong in wire format.
  • VS Code settings or similar tooling? Use JSONC — it's already supported.
  • Application config file? Use YAML, TOML, or JSON5 for human readability.
  • Quick workaround without new parsers? Use a "_comment" key.

Validate your JSON at JSONKit's validator to confirm your file is comment-free and parse-ready before shipping.

Try JSON Validator

Check your JSONC or JSON5 is comment-free and valid before parsing.