Skip to content
Eugene Lazutkin edited this page Aug 28, 2026 · 7 revisions

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.

Introduction

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));

Tokens

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 packComments to process long comments in constant memory.

API

jsoncParser(options)

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));

Options

All standard Parser options are supported:

  • packValues, packKeys, packStrings, packNumbers
  • streamValues, streamKeys, streamStrings, streamNumbers
  • jsonStreaming

Plus JSONC-specific options:

  • streamWhitespace — emit whitespace tokens. Default: true. Set to false to skip whitespace tokens (behaves like the standard parser for whitespace).
  • streamComments — emit startComment / commentChunk / endComment tokens. Default: true.
  • packComments — emit commentValue tokens holding the whole comment. Default: true. With both streamComments and packComments off, comments are consumed silently.
  • streamCommas — emit a valueless comma token 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 its useCommas option. Off by default because commas are structural: normal processing doesn't need them and the stringer auto-inserts separators.

Static methods and properties

jsoncParser.parser(options)

Alias of the factory function.

jsoncParser.asStream(options)

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));

Trailing commas

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 ones

Suppressing whitespace and comments

To 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})]);

Web Streams

jsoncParser ships in two substrate-specific entries with the same factory shape:

  • Node — stream-json/jsonc/parser.js. Has asStream (Node Duplex) and asWebStream (Web {readable, writable} pair).
  • Web — stream-json/web/jsonc/parser.js. Has asWebStream only. 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);

Clone this wiki locally