JSON6 The JSON6 Specification

What JSON6 is, where it came from, what it is designed to do, and how its json-6 reference implementation has changed.

TL;DR: JSON6 has no standards-body specification. The definition is the README plus the json-6 reference parser by d3x0r (MIT, current release 1.1.7), and this site documents what that parser actually does, verified by running it. JSON6 contains everything in JSON5 and adds back-tick strings, multi-line strings, \u{...} escapes, _ digit separators, 0b and 0o numbers, leading-zero decimals, extra signs, undefined and empty array members.

What the JSON6 spec is

JSON6 is a data format that extends JSON in the same spirit as JSON5, but further. It is not an RFC, an ECMA standard or a W3C recommendation, and it makes no claim to be. The project README says so directly: JSON6 is "not an official successor to JSON", and JSON6 content "may not work with existing JSON parsers", which is why files use their own extension, .json6. The README also lists a new MIME type as a to-do, so there is no registered media type for JSON6 today.

The practical consequence is that "the spec" is a living pair of artifacts: the feature list in the README.md of the json-6 npm package, and the parser source in lib/json6.js. This reference follows a simple rule that the README itself would endorse. When the two disagree, the code wins, because the code is what actually accepts or rejects your file. Every claim on the six specification pages was checked by running json-6 1.1.7 under Node.js, and every place where the code differs from the documentation or from what you might expect is called out in a note.

JSON6 adds no new data types. A JSON6 document still produces the same six kinds of value as JSON (object, array, string, number, boolean, null) plus the JavaScript undefined value, and numbers are still IEEE 754 double-precision floats. All of the additions are about how those values are written down, not about what they can hold. That is the main difference from its sibling format JSOX, covered below.

How this specification is organized

  • Syntax: whitespace, comments, keywords, document structure and a grammar summary.
  • Strings: the three quote styles, multi-line strings, every escape sequence, and what happens to unknown escapes.
  • Numbers: decimal, hexadecimal, octal, binary, underscores, signs, Infinity, NaN and precision limits.
  • Objects and arrays: key forms, keyword keys, duplicate keys, trailing commas and empty array members.
  • JSON5 differences: an exhaustive comparison and what breaks when you move files between the two formats.

History of JSON6

JSON6 is the work of a single developer who publishes as d3x0r. The repository is github.com/d3x0r/JSON6 and the package is json-6 on npm. The npm registry shows the first release, 0.1.0, on 2017-07-13, a long run of 0.1.x releases through January 2018, and version 1.0.0 on 2018-04-21. The 1.0.x line ran until December 2020 and 1.1.1 followed in January 2021.

The README states that its documentation base was cloned from the JSON5 project, and the feature list is written as a delta against JSON5: "JSON6 includes all features of JSON5 plus the following." That framing is a good way to think about the format. JSON5 asked what JSON would look like if it borrowed the friendly parts of ECMAScript 5.1. JSON6 asked what would happen if it also borrowed the friendly parts of ECMAScript 6 and then went a few steps past what JavaScript itself allows.

The package then went quiet. Version 1.1.4 was published on 2021-10-18 and the next release, 1.1.5, did not appear until 2026-10-11, a gap of five years. Versions 1.1.5 and 1.1.6 were published within hours of each other on 2026-10-11, and 1.1.7 followed on 2026-10-16. Those three releases are a substantial rework of the parser, the type declarations and the documentation, described in the version history below.

Relationship to JSOX

The README points to JSOX, "JS Object Exchange format", by the same author. JSOX builds on JSON6 and adds support for dates, big numbers, custom emissions, keyword-less class definitions, default initializers and more. It also has an IETF Internet-Draft (draft-buckeyne-jsox-format). If you need typed values that JSON6 cannot express, JSOX is the author's answer. If you need only a friendlier way to write JSON, JSON6 is the smaller format, and it deliberately stays at six data types.

Other implementations

The README mentions exactly one other implementation: the native Node.js addon sack.vfs, from the same author, which includes a C++ JSON6 parser. We found no independent third-party JSON6 parser for Python, Go, Rust or other languages while preparing this reference, so JSON6 is effectively a JavaScript-and-Node.js format today. The README also claims JSON6 is nearly twice as fast as the JSON5 parser, a figure it labels subjective; we did not benchmark it.

Design goals

The README states the motivation plainly: JSON is a good data format, but it is not friendly to write. Keys need quotes, objects and arrays cannot have trailing commas, and comments are forbidden, "even though none of these are the case with regular JavaScript today." JSON has grown from a machine format into one that humans edit: configuration files, manifests and test fixtures. The goals that follow from that are visible all through the grammar.

  • Stay close to JSON and JavaScript. The README contrasts JSON6 with YAML: moving to a completely different format is undesirable in many cases, so JSON6 aims to "remain close to JSON and JavaScript." The README says JSON6 "works with all existing JSON content", and the differences page lists the few places where the reverse is not true.
  • Be forgiving to humans. Leading zeros that align columns, literal newlines inside quoted strings, punctuation in unquoted keys such as content-type, and stray signs are all accepted by default. The README has a section titled "Why the default is not strict" that defends each one.
  • Mean what Number() means. The README's rule for numbers is that "a numeric token means what Number() says it means," which is why 0123 is 123 and not octal 83.
  • Add no new data types. The additions are syntax only.
  • Offer an opt-in strict mode. Since 1.1.6 the esStrictCompatible option narrows the grammar to a subset of ECMAScript strict mode, so a document that parses can be pasted into a module unchanged.

JSON6 is a permissive format by design. A parser that accepts {a-b: 0123} will happily accept typos that a stricter format would reject. For files that other tools must read, consider turning on esStrictCompatible or running the file through a validator before you ship it.

The additions, at a glance

This is the full set of additions that JSON6 makes beyond JSON5, each of which is verified in detail on a following page. JSON5 itself already adds comments, trailing commas, unquoted keys, single-quoted strings, hexadecimal numbers, Infinity, NaN, explicit plus signs, leading and trailing decimal points, and line continuations in strings.

FeatureExampleResultDetails
Back-tick strings`hello`"hello"Strings
Multi-line strings in any quote style'one two'newline preservedStrings
Long unicode escape"\u{1F600}"one emoji code pointStrings
Underscore separators1_000_0001000000Numbers
Binary and octal0b101 and 0o175 and 15Numbers
Leading-zero decimals0123123Numbers
Multiple signs---123-123Numbers
undefined keyword{a: undefined}{a: undefined}Syntax
Empty array members[1,,2]sparse array with a holeObjects and arrays
Back-tick keys{`a b`: 1}{"a b": 1}Objects and arrays
Extra whitespaceNBSP, VT, FF, U+2028, U+2029, BOMtreated as whitespaceSyntax
Streaming readerJSON6.begin(cb)values delivered as they completeStreaming
{ foo: 'bar', while: true, nothing: undefined, // why not? hex: 0xDEAD_beef, binary: 0b0110_1001, octal: 0o123, negative: ---123, to: Infinity, list: [1,, 3,], `back-tick key`: `a ${not} template`, }

The block above is a valid JSON6 document. Parsing it with json-6 1.1.7 gives a plain JavaScript object in which negative is -123, list is a three-element array with a hole in the middle, and the back-tick string keeps its ${not} text literally.

The reference API

The json-6 package exports a JSON6 object that mirrors the native JSON object. The module object exposes exactly these members, verified by listing its keys: parse, stringify, escape, begin, stringifier, stringifierActive and version.

MemberSignatureNotes
parseparse(text[, reviver][, options])Returns the first complete value in the text. The reviver also receives the root value, so parse("2", (k, v) => v * 10) returns 20 (fixed in 1.1.7).
stringifystringify(value[, replacer][, space][, options])Emits JSON6 text, not JSON. options.sortKeys defaults to true.
escapeescape(string)Backslash-escapes the double quote, single quote, back-tick and backslash only.
beginbegin(callback[, reviver][, options])Creates a streaming parser with write(), value() and reset().
stringifierstringifier()Returns a reusable stringifier with sortKeys and ignoreNonEnumerable properties.
versionJSON6.versionThe string "1.1.7" in the installed package.

The four parse options are all off by default, which means that out of the box the parser accepts the full historical grammar. They are esStrictCompatible, forbidTemplateSubstitution, normalizeNumericKeys and warnWithCommentWithoutEOL. Each is covered where it matters: on the strings, numbers and objects and arrays pages. An option name that json-6 does not know is silently ignored, so a typo in an option name disables the check without any error.

For Node.js there is a require('json-6/lib/require') hook that registers the .json6 extension, an ES module loader started with node --import json-6/lib/register.mjs (Node 20.6 or newer), an older --experimental-loader json-6/lib/import.mjs form, and a json-6 -c file.json6 command-line converter that writes a sibling .json file. TypeScript declarations ship in the package. Task-oriented guides are on the Node.js, TypeScript and CLI pages.

Version history of json-6

The table lists every release since 1.1.3, with the publication dates taken from the npm registry. The change notes are condensed from the README changelog shipped inside the package. Release 1.1.8 appears in the README as a "pre" heading with no entries and has not been published.

VersionPublishedChanges
1.1.32021-10-13Fixed \v decoding and hexadecimal numbers that use the letters a to f.
1.1.42021-10-18Fixed the benchmark test for hexadecimal conversion. Last release for five years.
1.1.52026-10-11TypeScript declarations generated from JSDoc and shipped in dist. ES module loader moved to the module.register() API with lib/register.mjs. Fixed the package exports map. Parser source moved to src/json6.js, with the version stamped into lib/json6.js. Documented why leading zeros are decimal.
1.1.62026-10-11Fixed the shipped json6.d.ts for TypeScript 5.x. Added the normalizeNumericKeys option. Corrected error line and column positions. stringify emits arrays as arrays, keeps holes, and always quotes string values. Malformed input that used to be accepted now throws: two values with no separator, a field name with no value, an incomplete keyword, a bare sign, a malformed number such as 1e, and a document with no value. begin() no longer needs a callback until write() is called. Vertical tab, form feed, U+2028 and U+2029 are whitespace. Added the parse options esStrictCompatible, forbidTemplateSubstitution and warnWithCommentWithoutEOL, and the sortKeys stringify option.
1.1.72026-10-16A reviver return value for the root is now used. stringify runs a replacer on the raw value before quoting. stringify quotes object keys containing brackets, quote characters or whitespace so they parse back. A comment may directly follow a number and a block comment closes after consecutive asterisks. A root string split across write() calls is delivered before the next value. README streaming examples corrected. npm test now type-checks test files.

The 1.1.6 line "Malformed input that used to be silently accepted now throws" matters if you have old data. Text such as [1 2] returned [2] under 1.1.4 and now throws. Pin your version, and re-run your corpus when you upgrade across the 1.1.4 to 1.1.5 boundary.

Surprises found while verifying the spec

Running the parser against the README turned up behavior that the documentation does not mention or only partly describes. None of these is a reason to avoid JSON6, but each is worth knowing before you build on it. They are repeated on the relevant pages.

  • parse() ignores everything after the first value. JSON6.parse("1 2") returns 1, JSON6.parse("[1] x") returns [1] and JSON6.parse("[1,2]]") returns [1,2] with no error. JSON5 throws for all three. Use JSON6.begin to read several values.
  • The key __proto__ changes the result's prototype. JSON6.parse("{__proto__:{x:1}}") returns an object with no own keys whose inherited x is 1. JSON5 creates an ordinary own property instead. This affects only the parsed object, not Object.prototype, but do not merge untrusted JSON6 into other objects without a guard.
  • A bare backslash plus carriage return continuation is mis-parsed. A backslash followed by a lone CR (no LF) and then a letter treats that letter as an escape, so "a\<CR>b" gives a backspace character. Backslash plus LF or CRLF works correctly.
  • stringify drops toJSON. JSON6.stringify({d: new Date(0)}) gives {d:{}}. Dates, Maps and Sets all become empty objects, unlike native JSON.stringify and JSON5.stringify.
  • stringify output is not JSON. It emits unquoted keys, escapes the single quote, back-tick and so on, writes literal newlines inside strings, and sorts keys by default. Never send it to a consumer that expects JSON. Use JSON.stringify for that.
  • Unquoted-key escapes are not decoded. {a\u0062: 1} produces the key a\u0062, not ab. JSON5 would decode it.
  • Only some Unicode spaces count as whitespace. NBSP, BOM, VT, FF, U+2028 and U+2029 are accepted, but the em space U+2003 and the ideographic space U+3000 are rejected, although JSON5 and ECMAScript accept them.

FAQ

Is there an official JSON6 specification?

No. There is no RFC, ECMA standard or formal grammar. The README and source of the json-6 package are the definition, and the author's other format, JSOX, is the one with an IETF Internet-Draft.

Who maintains JSON6?

d3x0r maintains the repository at github.com/d3x0r/JSON6 and the json-6 package on npm. It is MIT licensed. Releases 1.1.5, 1.1.6 and 1.1.7 appeared in October 2026 after a five-year gap.

Is JSON6 a superset of JSON?

For syntax, yes: every valid JSON document parses. The README, however, deliberately avoids calling JSON6 a superset of JavaScript, and 1.1.7 reworded the README to say JSON6 "extends JSON". JSON6 also accepts some invalid input that JSON parsers reject, such as trailing text after the first value.

What file extension and MIME type does JSON6 use?

The extension is .json6. The README lists a new MIME type as a to-do, so none is registered and servers should treat .json6 files as plain text or application/octet-stream.

Does JSON6 have a formal grammar?

Not from the project. The syntax page gives a grammar summary that we derived by testing the parser. Treat it as a description, not as normative text.

Try the JSON6 syntax yourself

Paste a document into the validator and see exactly how json-6 reads it.