Migrating from 1.x to 2.x - uhop/stream-json GitHub Wiki

This page covers migrating from stream-json 1.x to 2.x. The main theme is a shift from class-based modules to functional factories built on stream-chain 3.4.x. All require() paths are unchanged — only usage patterns differ.

If you feel that some fine points are missing or covered incorrectly, please suggest an edit.

Overview of changes

Area 1.x 2.x
Module style Class-based (new Stringer(options)) Functional factories (stringer(options))
.make() Available on all rewritten modules Removed — use factory directly or .asStream()
instanceof stream instanceof Stringer Not available for rewritten modules
Utf8Stream Active Deprecated — use fixUtf8Stream from stream-chain
stream-chain 3.x 3.4.x required
TypeScript Bundled .d.ts Updated to function+namespace pattern

What didn't change

These modules were already functional in late 1.x and are unchanged in 2.x:

Breaking changes

.make() removed

All rewritten modules no longer have .make(). Replace with the factory function or .asStream():

// 1.x
const Stringer = require('stream-json/stringer.js');
const stream = Stringer.make(options);

// 2.x — for .pipe() usage
const stringer = require('stream-json/stringer.js');
const stream = stringer.asStream(options);

// 2.x — for chain() usage (preferred)
const stringer = require('stream-json/stringer.js');
chain([source, parser(), stringer(options)]);

new Constructor() removed

Rewritten modules are no longer classes. Using new will throw:

// 1.x
const stream = new Stringer(options);
const stream = new Emitter(options);
const stream = new Batch(options);
const stream = new Verifier(options);

// 2.x
const stream = stringer.asStream(options);
const stream = emitter(options);
const stream = batch.asStream(options);
const stream = verifier.asStream(options);

instanceof checks

If your code uses instanceof on rewritten modules, it will no longer work:

// 1.x
if (stream instanceof Stringer) { ... }

// 2.x — not possible for rewritten modules
// Use duck typing or check stream properties instead

Module-by-module migration

Stringer

Stringer is now a flushable function. Use stringer() in chain() or stringer.asStream() for .pipe().

// 1.x
const Stringer = require('stream-json/stringer.js');
chain([source, parser(), pick({filter: 'data'}), Stringer.make()]);
// or: source.pipe(parser.asStream()).pipe(Stringer.make());

// 2.x
const stringer = require('stream-json/stringer.js');
chain([source, parser(), pick({filter: 'data'}), stringer()]);
// or: source.pipe(parser.asStream()).pipe(stringer.asStream());

All options (useValues, useKeyValues, useStringValues, useNumberValues, makeArray) work identically.

1.x 2.x
Stringer.make(options) stringer.asStream(options)
Stringer.stringer(options) stringer.asStream(options)
new Stringer(options) stringer.asStream(options)
(in chain) Stringer.make() stringer()

Emitter

Emitter is now a factory returning a Writable. Since it's a stream endpoint, both the factory and .asStream() return the same thing.

// 1.x
const Emitter = require('stream-json/emitter.js');
const e = Emitter.make();
chain([source, parser(), e]);
e.on('startObject', () => console.log('object!'));

// 2.x
const emitter = require('stream-json/emitter.js');
const e = emitter();
chain([source, parser(), e]);
e.on('startObject', () => console.log('object!'));
1.x 2.x
Emitter.make(options) emitter(options)
Emitter.emitter(options) emitter(options)
new Emitter(options) emitter(options)

Batch

Batch is now a flushable function wrapping stream-chain/utils/batch.

// 1.x
const Batch = require('stream-json/utils/batch.js');
chain([source, streamArray.withParser(), Batch.make({batchSize: 100})]);

// 2.x
const batch = require('stream-json/utils/batch.js');
chain([source, streamArray.withParser(), batch({batchSize: 100})]);
1.x 2.x
Batch.make(options) batch.asStream(options)
Batch.batch(options) batch.asStream(options)
new Batch(options) batch.asStream(options)
(in chain) Batch.make() batch()

The _batchSize property is still available on streams returned by batch.asStream().

Verifier

Verifier is now a gen(fixUtf8Stream(), validate) pipeline.

// 1.x
const Verifier = require('stream-json/utils/verifier.js');
const v = Verifier.make();
v.on('error', err => console.log(err));
fs.createReadStream('data.json').pipe(v);

// 2.x
const verifier = require('stream-json/utils/verifier.js');
const v = verifier.asStream();
v.on('error', err => console.log(err));
fs.createReadStream('data.json').pipe(v);
1.x 2.x
Verifier.make(options) verifier.asStream(options)
Verifier.verifier(options) verifier.asStream(options)
new Verifier(options) verifier.asStream(options)
(in chain) Verifier.make() verifier()

Error objects still have offset, line, and pos properties.

jsonl/Parser

JsonlParser is now a gen(fixUtf8Stream(), lines(), parseLine) pipeline.

Consider using stream-chain directly. If you don't need errorIndicator or checkErrors, stream-chain/jsonl/parser is a lighter alternative that produces the same {key, value} output:

// 1.x
const JsonlParser = require('stream-json/jsonl/parser.js');
fs.createReadStream('data.jsonl').pipe(JsonlParser.make());

// 2.x — stream-chain (recommended for simple cases)
const jsonlParser = require('stream-chain/jsonl/parserStream.js');
fs.createReadStream('data.jsonl').pipe(jsonlParser());

// 2.x — stream-json (when you need errorIndicator/checkErrors)
const jsonlParser = require('stream-json/jsonl/parser.js');
fs.createReadStream('data.jsonl').pipe(jsonlParser.asStream({errorIndicator: null}));
1.x 2.x
JsonlParser.make(options) jsonlParser.asStream(options)
JsonlParser.parser(options) jsonlParser.asStream(options)
new JsonlParser(options) jsonlParser.asStream(options)
(in chain) JsonlParser.make() jsonlParser()

stream-chain vs stream-json JSONL parser:

Feature stream-chain/jsonl/parser stream-json/jsonl/parser
reviver
ignoreErrors (boolean)
errorIndicator (function/value)
checkErrors
checkedParse() static
Output format {key, value} {key, value}

If you only need reviver and optionally ignoreErrors, use stream-chain directly.

jsonl/Stringer

JsonlStringer now delegates to stream-chain/jsonl/stringerStream. You can use stream-chain directlystream-json/jsonl/stringer.js is a thin wrapper:

// 1.x
const JsonlStringer = require('stream-json/jsonl/stringer.js');
chain([source, JsonlParser.make(), data => data.value, JsonlStringer.make()]);

// 2.x — stream-chain (recommended)
const jsonlStringer = require('stream-chain/jsonl/stringerStream.js');
chain([source, jsonlParser(), data => data.value, jsonlStringer()]);

// 2.x — stream-json (same result, just a re-export)
const jsonlStringer = require('stream-json/jsonl/stringer.js');
chain([source, jsonlParser(), data => data.value, jsonlStringer()]);
1.x 2.x
JsonlStringer.make(options) jsonlStringer(options)
JsonlStringer.stringer(options) jsonlStringer(options)
new JsonlStringer(options) jsonlStringer(options)

The stream-chain version supports additional options: prefix, suffix, space, emptyValue.

Deprecations

Utf8Stream

Utf8Stream is deprecated. Use fixUtf8Stream from stream-chain instead:

// 1.x
const Utf8Stream = require('stream-json/utils/utf8-stream.js');
source.pipe(new Utf8Stream());

// 2.x
const {chain} = require('stream-chain');
const fixUtf8Stream = require('stream-chain/utils/fixUtf8Stream.js');
chain([source, fixUtf8Stream()]);

The module still works but emits a DeprecationWarning once per process. It will be removed in 3.0.0.

Quick-reference cheat sheet

// 2.x imports — all require() paths unchanged, just use the result differently
const stringer = require('stream-json/stringer.js');
const emitter = require('stream-json/emitter.js');
const batch = require('stream-json/utils/batch.js');
const verifier = require('stream-json/utils/verifier.js');
const jsonlParser = require('stream-json/jsonl/parser.js');
const jsonlStringer = require('stream-json/jsonl/stringer.js');

// In chain() — use the factory directly (returns a function)
chain([source, parser(), stringer()]);
chain([source, parser(), streamArray(), batch({batchSize: 100})]);
chain([source, verifier()]);
chain([source, jsonlParser()]);

// For .pipe() — use .asStream() (returns a Node stream)
source.pipe(parser.asStream()).pipe(stringer.asStream());
source.pipe(jsonlParser.asStream());
source.pipe(verifier.asStream());

// Emitter and jsonlStringer return streams directly
const e = emitter();
source.pipe(parser.asStream()).pipe(e);
⚠️ **GitHub.com Fallback** ⚠️