Why Choose JSON6?
What JSON6 gives you over JSON and JSON5, what it costs, and when it is the wrong tool.
TL;DR: Choose JSON6 when people hand-write data and want JSON5's comfort plus digit separators, binary and octal numbers, back-tick strings and real multi-line strings, and when you control the code that reads the file. Skip it when other teams, other languages or other tools must read the same file.
The problem JSON6 is trying to solve
JSON is an excellent data interchange format and a mediocre editing format. It was designed so machines could exchange data safely, and it does that job well. But a great deal of JSON is now written and maintained by people: configuration files, manifests, test fixtures, seed data. In those files the rules that make JSON easy to parse get in the way. Keys must be quoted. A trailing comma is a syntax error, so reordering the last two lines of a list breaks the file. There are no comments, so the reason a value was chosen cannot live next to the value.
JSON5 fixed the most visible of these by borrowing syntax from ECMAScript 5. JSON6 starts from the same idea and keeps going. Its README states the goal directly: add a minimal set of syntax features from ECMAScript 6 so that humans can write and maintain data by hand, while adding no new data types and working with all existing JSON content. The result is a format that reads like the object literals developers already write every day.
The project is also candid about what it is not. JSON6 is described as a proposed extension to JSON, not an official successor, and the README warns that JSON6 content may not work with existing JSON parsers. That is the reason for the dedicated .json6 file extension. This site takes the same position: JSON6 is a useful tool with a clear scope, not a replacement for JSON.
What you get beyond JSON5
Everything JSON5 allows, JSON6 allows: comments, trailing commas, unquoted keys, single-quoted strings, hex numbers, Infinity and NaN, leading and trailing decimal points, an explicit plus sign. On top of that, the json-6 parser (version 1.1.7 at the time of writing) accepts the following. Each one is covered in depth in the JSON5 differences reference.
Back-tick strings
A third quote character, usable for values and for object keys. Template substitution does not exist, so ${name} is plain text unless you call for an error with forbidTemplateSubstitution.
Multi-line strings everywhere
Every string style may contain raw line breaks and keeps them. End a line with a backslash if you want the break removed instead.
Underscore separators
1_000_000 and 0xDEAD_beef read like the numeric separator proposal in ECMAScript, with a few looser placements.
Binary and octal
0b1011 and 0o755 alongside 0x1F. Leading-zero decimals such as 0042 are decimal, not octal.
Empty array members
[1,,3] yields an array with a hole at index 1, the same as JavaScript.
A streaming reader
JSON6.begin() returns a parser that accepts text in chunks and calls you back for each complete value. See streaming.
The same README lists a few smaller items: the undefined keyword, multiple leading signs (----123 is 123), back-tick object keys, and a wider set of whitespace characters (no-break space, vertical tab, form feed, and the line and paragraph separators U+2028 and U+2029).
// All of this parses with JSON6.parse() and none of it parses with JSON.parse() { permissions: 0o755, mask: 0b1111_0000, population: 8_100_000_000, banner: `Line one Line two`, sparse: [1,, 3], unset: undefined, }The costs, stated plainly
It is not a standard
JSON has an ECMA standard (ECMA-404) and an IETF RFC (8259). JSON5 has a published specification. JSON6 has a README and a reference implementation. Where the README is silent, the behavior of the json-6 parser is the specification, and the parser is deliberately permissive. For example, in version 1.1.7 JSON6.parse('{a:1} trailing garbage') returns { a: 1 } without complaint, because the parser stops after the first complete value. If you want to reject trailing input you must check for it yourself.
The ecosystem is small
There is one maintained parser, json-6 on npm, written in JavaScript. The README also mentions that JSON6 is implemented in the sack.vfs native Node.js addon by the same author. We could not find editor extensions, linters, bundler plugins or ports to other languages dedicated to JSON6, and this site does not pretend otherwise. If you work in Python, Go, Rust or Java, JSON6 is not a practical choice today. The workaround for editors is covered on the editors page: JSON5 or JavaScript highlighting works for most of the syntax.
It is permissive by default
The same leniency that makes hand-editing pleasant also accepts things that might be typos: ---5 is 5, 0123 is 123, 1__0 is 10, and an unquoted key can contain a hyphen. The parser offers opt-in options for stricter behavior, described below, but nothing is strict unless you ask.
A single maintainer
The project is the work of one author. Releases 1.1.5, 1.1.6 and 1.1.7 shipped in October 2026 after a gap since 1.1.4 in 2021, and the 1.1.6 release fixed a number of parsing and stringifying bugs, including arrays that stringified as objects and several malformed inputs that were silently accepted. That is encouraging activity, and also a reminder that the project is young again and moving. Pin your version.
Choosing how strict to be
Four parse options exist, all off by default. They let one library serve both a forgiving config loader and a stricter pipeline:
| Option | When enabled |
|---|---|
esStrictCompatible | Narrows the grammar to a subset of ECMAScript strict mode so anything accepted can be pasted into a module. Rejects leading-zero numbers, legacy octal escapes, raw line breaks in ' and " strings, back-tick keys, non-identifier unquoted keys and repeated signs. |
forbidTemplateSubstitution | Throws on an unescaped ${ inside a back-tick string, so a file cannot silently turn into a template literal later. |
normalizeNumericKeys | Turns an unquoted numeric key such as 1e3 into "1000", as a JavaScript object literal would. |
warnWithCommentWithoutEOL | Logs a console warning when a // comment ends the document without a line break. |
A sensible rule: leave the defaults on for files only your team edits, and turn on esStrictCompatible when a file must double as JavaScript or when a stricter reviewer is easier than a surprised one. Details are in the spec overview.
JSON6 versus the alternatives
The right format depends on who reads the file. A short guide, with the full matrix on the comparison page:
- Plain JSON for APIs, storage and anything exchanged between systems. Native parsers are everywhere and fast.
- JSONC when your tool already reads it (editor settings, TypeScript configs) and you only need comments.
- JSON5 when you want human-friendly syntax and need parsers in several languages and a published specification.
- JSON6 when you want JSON5 plus numeric separators, binary and octal, back-ticks and multi-line strings, and you load files from JavaScript or TypeScript.
- JSOX when you want JSON6 syntax plus richer types such as dates and big integers, from the same author.
- YAML or TOML when you are happy to leave the JSON family for a different layout. YAML is indentation based; TOML is table based and has native dates.
A pattern that works well: write the source of truth in JSON6 for humans, and convert to plain JSON at build time with the json-6 -c command line tool, so everything downstream receives standard JSON. The migration tutorial walks through it.
One rule of thumb: if the bytes cross a team boundary, send JSON. If they stay inside your repository and your Node.js process, JSON6 is a comfortable choice. Our JSON5 migration guide covers the move between the two.
Performance and dependencies
The README claims the parser is about as fast as Douglas Crockford's reference json_parse.js and nearly double the speed of the JSON5 implementation that inspired it, and it carries the caveat "subjective" next to that comparison. Treat it as a design goal, not a benchmark you can quote. Native JSON.parse() in a modern engine is faster than any JavaScript-implemented parser, which is another reason to use JSON for hot paths. For a config file loaded once at startup the difference is not measurable in practice.
The package declares no runtime dependencies, ships TypeScript declarations and works in Node.js and, through its browser bundle, in browsers. The README states Node 10 as the minimum for the library itself; the ES module loader hook needs Node 20.6 or newer. The Node.js guide and browser guide cover installation.
FAQ
Is JSON6 a superset of JSON5?
The README says JSON6 "includes all features of JSON5 plus" its own additions, so a valid JSON5 document should parse with json-6. The reverse is false: back-ticks, underscores, 0b and 0o numbers and empty array members are JSON6-only.
Does JSON6 add new data types?
No. The project states it adds no new data types. undefined is a keyword, but it is not representable in JSON. For dates and big integers look at JSOX.
Can I use JSON6 for package.json?
No. npm needs standard JSON. The json-6 project itself keeps a package.json6 and generates package.json with a build step, which is a good model to copy.
Is it safe to parse untrusted JSON6?
The parser reads data, it does not execute code. It is less strict than JSON, so validate the parsed value as you would any input, and use forbidTemplateSubstitution if the text might later be evaluated as JavaScript.
More answers are on the full FAQ.
Try It on a Real File
Paste your own JSON6 into the online validator and see exactly how the parser reads it.