JSON5 and JSONC Formatter

Beautify configuration files that use comments, trailing commas or unquoted keys. Comments stay exactly where you wrote them.

Input

Settings

History

Load from URL

JSON5 vs JSONC: two different supersets

Plain JSON has no comments, which is why a lot of tooling quietly accepts a looser dialect. There are two in common use, and they are not the same thing:

  • JSONC (“JSON with comments”) is JSON plus // and /* */ comments and, in most readers, trailing commas. It is what tsconfig.json, .vscode/settings.json, devcontainer.json and .eslintrc.json actually contain. Keys and strings still need double quotes.
  • JSON5 goes further and follows ES5 object-literal syntax: unquoted keys, single-quoted strings, hexadecimal numbers like 0x1F, leading or trailing decimal points, +1, Infinity and NaN. Babel configs (.babelrc.json5) and some game and build tools use it.

A file that is valid JSONC is usually valid JSON5 too, but not the other way round: {name: 'app'} is JSON5 only. Feeding it to a JSONC reader such as VS Code’s settings parser fails.

Using the formatter

Paste the file or drop a .json5 / .jsonc file on the input pane. Auto-detection picks this formatter when the text has comments or trailing commas that strict JSON rejects. Ctrl/Cmd+Enter formats, Ctrl/Cmd+Shift+C copies the result, and Ctrl/Cmd+K opens the command palette. A Tree view lets you fold large configs such as an ESLint flat config exported to JSON.

Beautifying is done by Prettier’s json5 and jsonc printers, so the output matches what Prettier produces in your editor. Validation uses the json5 package or Microsoft’s jsonc-parser (the one VS Code uses), so error messages follow the dialect you are writing. Your config never leaves the browser, which is worth knowing when it embeds a registry token or connection string.

Options explained

  • Variant: Auto-detect looks for JSON5-only syntax (unquoted keys, single quotes, hex numbers, NaN) and otherwise treats the input as JSONC. Force JSON5 or JSONC (JSON with comments) when you want the validator to enforce one dialect, for example to prove a tsconfig.json will load in TypeScript.
  • Quote keys: As written leaves each key alone. Only where needed removes quotes that are not required ("port" becomes port), which only makes sense for JSON5. All or none per object quotes every key in an object if any key needs quotes.
  • Trailing commas: Remove strips them, which is the safest choice for files other tools also read. Add to multi-line objects and arrays puts a comma after the last element whenever the object spans several lines, so future additions produce one-line diffs.

Indent and line width apply as usual.

What happens to comments

In normal formatting, line and block comments are preserved and re-indented with the code around them. Two operations work on the parsed data instead of the text, and therefore cannot keep comments: Minify and Sort keys. When either is used on a file that contains comments, an info note (“Minifying removes comments” or “Sorting keys removes comments”) tells you before you copy the output. Minified JSONC output is plain JSON, so it is also a quick way to produce a strict-JSON copy of a commented config; the JSON5 to JSON converter does the same with type-aware handling of Infinity and NaN.

Examples

tsconfig.json with comments and trailing commas

Both comments survive, and the trailing commas are removed because Trailing commas defaults to Remove.

Input
{
  // Shared compiler settings for the web app
  "compilerOptions": {"target": "ES2022", "module": "ESNext", "moduleResolution": "bundler",
    "strict": true, /* catch implicit any */ "noUncheckedIndexedAccess": true,
    "paths": {"@app/*": ["src/*"], "@ui/*": ["packages/ui/src/*"],},
  },
  "include": ["src", "vite.config.ts",],
}
Output
{
  // Shared compiler settings for the web app
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    /* catch implicit any */ "noUncheckedIndexedAccess": true,
    "paths": { "@app/*": ["src/*"], "@ui/*": ["packages/ui/src/*"] }
  },
  "include": ["src", "vite.config.ts"]
}
Open this example in the tool

JSON5 build config with unquoted keys

Hex numbers and single-quoted strings are accepted, quotes are dropped from keys that do not need them, and multi-line objects gain trailing commas.

Input
// build.json5
{name: 'checkout-service', version: '2.4.0', port: 8080,
  retry: {attempts: 3, backoffMs: 250, jitter: .2},
  flags: ['payments', 'refunds',], maxBody: 0x100000, 'content-type': 'application/json',}
Output
// build.json5
{
  name: "checkout-service",
  version: "2.4.0",
  port: 8080,
  retry: { attempts: 3, backoffMs: 250, jitter: 0.2 },
  flags: ["payments", "refunds"],
  maxBody: 0x100000,
  "content-type": "application/json",
}
Open this example in the tool

VS Code settings.json

A typical user settings file is re-indented to two spaces while the comment stays above the line it describes.

Input
{
    "editor.formatOnSave": true,
    // Prettier for everything except Python
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "[python]": {"editor.defaultFormatter": "charliermarsh.ruff"},
    "files.exclude": {"**/node_modules": true, "**/.turbo": true}
}
Output
{
  "editor.formatOnSave": true,
  // Prettier for everything except Python
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "[python]": { "editor.defaultFormatter": "charliermarsh.ruff" },
  "files.exclude": { "**/node_modules": true, "**/.turbo": true }
}
Open this example in the tool

Common errors and how to fix them

ErrorCauseFix
Expected a property name in double quotes
Explained
The file is being read as JSONC, which still requires double-quoted keys, but a key is unquoted or single-quoted.Quote the key with double quotes, or set Variant to JSON5 if the consuming tool really accepts JSON5.
Missing comma
Explained
A JSONC property follows the previous one without a comma, often because a comment line was inserted between them.Add a comma at the end of the property before the comment, not after the comment.
Invalid character 'b'The JSON5 parser met a character it did not expect, here a second key with no comma before it ({a: 1 b: 2}).Look just before the reported column: a missing comma or colon is the usual culprit.
Unterminated block commentA /* comment has no closing */, so the rest of the file was swallowed into the comment.Add */ where the comment should end; editors highlight the whole remainder as a comment, which makes the spot easy to find.
Invalid character 'u'
Explained
The value undefined is not part of JSON5 or JSONC, even though JavaScript object literals allow it.Use null, or remove the property entirely.

Frequently asked questions

Is tsconfig.json JSON or JSONC?

It is JSONC: TypeScript accepts comments and trailing commas in tsconfig.json. Running it through a strict JSON parser such as JSON.parse or jq will fail, so format it here with Variant set to JSONC.

Will formatting remove my comments?

No. Beautifying keeps every comment in place. Only Minify and Sort keys drop comments, and both show a note when that happens.

How do I convert JSON5 to plain JSON?

Use Minify on this page for a compact strict-JSON copy, or the JSON5 to JSON converter for indented output. Comments are removed in both cases because JSON has no syntax for them.

Why does VS Code show "Comments are not permitted in JSON"?

The file is associated with the JSON language mode instead of JSON with Comments. Click the language indicator in the status bar and choose “JSON with Comments”, or add a files.associations entry mapping the file name to jsonc.

Does the formatter accept NaN and Infinity?

In JSON5 mode, yes, because JSON5 allows them. JSONC and plain JSON reject them; a JSON consumer will need null or a string instead.

Related tools