Skip to content
Eugene Lazutkin edited this page May 29, 2026 · 3 revisions

This is a JSONC stringer that converts a token stream (including whitespace, comment, and comma tokens from the JSONC Parser) back into JSONC text.

Base tokens are handled identically to Stringer. Whitespace and comment tokens are output verbatim; with useCommas, comma tokens are rendered too.

Introduction

const {chain} = require('stream-chain');
const {parser: jsoncParser} = require('stream-json/jsonc/parser.js');
const {stringer: jsoncStringer} = require('stream-json/jsonc/stringer.js');

const fs = require('fs');

const pipeline = chain([fs.createReadStream('settings.jsonc'), jsoncParser(), jsoncStringer()]);

let result = '';
pipeline.on('data', chunk => (result += chunk));
pipeline.on('end', () => console.log(result));

API

jsoncStringer(options)

The factory function. Returns a flushable function for use in chain():

const {chain} = require('stream-chain');
const {parser: jsoncParser} = require('stream-json/jsonc/parser.js');
const {stringer: jsoncStringer} = require('stream-json/jsonc/stringer.js');

const fs = require('fs');

const pipeline = chain([fs.createReadStream('settings.jsonc'), jsoncParser(), jsoncStringer()]);

let result = '';
pipeline.on('data', chunk => (result += chunk));
pipeline.on('end', () => console.log(result));

Options

All standard Stringer options are supported:

  • useValues, useKeyValues, useStringValues, useNumberValues
  • makeArray

Plus a JSONC-specific option:

  • useCommas — render streamed comma tokens (from the parser's streamCommas) as , instead of auto-generating separators. Default: false. A separator is still auto-inserted before a value when no comma token preceded it, so the output stays valid even if a comma was dropped by an upstream transform.

Static methods and properties

jsoncStringer.stringer(options)

Alias of the factory function.

jsoncStringer.asStream(options)

Returns a Duplex stream (object-mode writable, text-mode readable):

const jsoncParser = require('stream-json/jsonc/parser.js');
const jsoncStringer = require('stream-json/jsonc/stringer.js');
const fs = require('fs');

const pipeline = fs.createReadStream('settings.jsonc').pipe(jsoncParser.asStream()).pipe(jsoncStringer.asStream());

let result = '';
pipeline.on('data', chunk => (result += chunk));
pipeline.on('end', () => console.log(result));

Round-tripping

When used with the JSONC parser, the stringer preserves whitespace and comments. By default, commas are auto-inserted by the stringer, so their placement may differ from the original and trailing commas are normalized away. For byte-faithful round-trips — e.g. streaming edits of large JSONC files that don't fit in memory — parse with streamCommas: true and stringify with useCommas: true; commas (including trailing commas) are then reproduced exactly at their original positions. Colons are always auto-inserted.

const {chain} = require('stream-chain');
const {parser: jsoncParser} = require('stream-json/jsonc/parser.js');
const {stringer: jsoncStringer} = require('stream-json/jsonc/stringer.js');
const {Readable} = require('node:stream');

const input = '{\n  // name\n  "a": 1\n}';
const pipeline = chain([Readable.from([input]), jsoncParser(), jsoncStringer()]);

let result = '';
pipeline.on('data', chunk => (result += chunk));
pipeline.on('end', () => console.log(result));
// Comments and whitespace are preserved in the output

Web Streams

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

  • Nodestream-json/jsonc/stringer.js. Has asStream (Node Duplex) and asWebStream (Web {readable, writable} pair).
  • Webstream-json/web/jsonc/stringer.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';
import {stringer as jsoncStringer} from 'stream-json/web/jsonc/stringer.js';

const pipeline = chain([source, jsoncParser(), jsoncStringer()]);
let result = '';
for await (const chunk of pipeline.readable) result += chunk;
console.log(result);

Clone this wiki locally