Repository navigation
jsonc Parser
Signature: text → tokens
This is a streaming JSONC (JSON with Comments) parser. It is a fork of the standard Parser with support for single-line (//) and multi-line (/* */) comments, trailing commas in arrays and objects, and optional whitespace tokens. See the JSONC specification.
It produces the same SAX-like token stream as the standard parser, plus the whitespace token type, comments in the same two forms as strings (streamed startComment / commentChunk / endComment and packed commentValue), and an optional comma token (see Options).
All existing components (filters, streamers, assembler, etc.) are compatible with the JSONC parser — they simply ignore tokens they don't recognize.
JSONC input is normally configuration you wrote. The parser is not designed for hostile input — do not feed it JSONC from the open internet or from untrusted users.
import jsoncParser from 'stream-json/jsonc/parser.js';
import fs from 'node:fs';
const pipeline = fs.createReadStream('settings.jsonc').pipe(jsoncParser.asStream());
pipeline.on('data', token => console.log(token));In addition to all standard parser tokens, the JSONC parser emits:
| Token name | Value | Meaning |
|---|---|---|
whitespace |
the whitespace characters | contiguous whitespace between tokens |
startComment |
— | a comment begins; with streamComments
|
commentChunk |
a piece of the comment text, delimiters included | may be split across input chunks |
endComment |
— | the comment ended |
commentValue |
the full comment including delimiters |
// ...\n or /* ... */; with packComments
|
comma |
— | a , (separator or trailing); emitted only with streamCommas
|
-
//comment values include the end-of-line character(s). At EOF without a trailing newline, the value has no EOL. -
/* */comment values include the/*and*/delimiters. - Comments mirror strings: the streamed form arrives in chunks and resumes across input chunk boundaries, so a comment of any length costs linear time; the packed form buffers the whole comment. Turn off
packCommentsto process long comments in constant memory.
The factory function. Returns a composable function for use in chain(). The JSONC parser uses the same charCodeAt tokenizer as the standard Parser; the named export jsoncParser is the raw inner tokenizer (no fixUtf8Stream() front), and the default/parser is gen(fixUtf8Stream(), jsoncParser()):
import chain from 'stream-chain';
import {parser as jsoncParser} from 'stream-json/jsonc/parser.js';
import fs from 'node:fs';
const pipeline = chain([fs.createReadStream('settings.jsonc'), jsoncParser()]);
pipeline.on('data', token => console.log(token));All standard Parser options are supported:
-
packValues,packKeys,packStrings,packNumbers -
streamValues,streamKeys,streamStrings,streamNumbers jsonStreaming
Plus JSONC-specific options:
-
streamWhitespace— emitwhitespacetokens. Default:true. Set tofalseto skip whitespace tokens (behaves like the standard parser for whitespace). -
streamComments— emitstartComment/commentChunk/endCommenttokens. Default:true. -
packComments— emitcommentValuetokens holding the whole comment. Default:true. With bothstreamCommentsandpackCommentsoff, comments are consumed silently. -
streamCommas— emit a valuelesscommatoken at the position of every comma (separator or trailing). Default:false. Turn it on for faithful round-trip editing: it lets the JSONC Stringer reproduce comma placement exactly — including trailing commas — via itsuseCommasoption. Off by default because commas are structural: normal processing doesn't need them and the stringer auto-inserts separators.
Alias of the factory function.
Returns a Duplex stream (text-mode writable, object-mode readable) wrapping the parser:
import jsoncParser from 'stream-json/jsonc/parser.js';
import fs from 'node:fs';
const pipeline = fs.createReadStream('settings.jsonc').pipe(jsoncParser.asStream());
pipeline.on('data', token => console.log(token));The JSONC parser accepts trailing commas in arrays and objects without error. By default they are consumed silently (no token). With streamCommas, every comma — separator and trailing — is surfaced as a valueless comma token at its position, so a parse → stringify round-trip can reproduce it faithfully:
import chain from 'stream-chain';
import {parser as jsoncParser} from 'stream-json/jsonc/parser.js';
import {Readable} from 'node:stream';
const pipeline = chain([Readable.from(['{"a": 1, "b": [2, 3,],}']), jsoncParser({streamCommas: true})]);
pipeline.on('data', token => console.log(token.name)); // emits `comma` tokens, including the two trailing onesTo get a token stream identical to the standard parser (minus trailing comma tolerance), disable all three options:
const pipeline = chain([source, jsoncParser({streamWhitespace: false, streamComments: false, packComments: false})]);jsoncParser ships in two substrate-specific entries with the same factory shape:
-
Node —
stream-json/jsonc/parser.js. HasasStream(Node Duplex) andasWebStream(Web{readable, writable}pair). -
Web —
stream-json/web/jsonc/parser.js. HasasWebStreamonly. Pulls in no Node-stream imports.
Both factories return the same flushable, so chain on either substrate auto-wraps it.
// Web
import {chain} from 'stream-chain/web';
import {parser as jsoncParser} from 'stream-json/web/jsonc/parser.js';
const pipeline = chain([source, jsoncParser()]);
for await (const tok of pipeline.readable) console.log(tok);Start here
Core
Filters
Streamers
Essentials
Utilities
File I/O (Node-only)
JSONC
JSONL (use stream-chain)
Reference
Built on stream-chain