@bybrave/concat-stream2
v3.0.1
Published
Maintained fork of concat-stream — zero runtime dependencies, dual ESM+CJS, and bundled TypeScript types (no separate @types/concat-stream needed)
Maintainers
Readme
@bybrave/concat-stream2
Maintained fork of concat-stream — a writable stream that concatenates all the data written to it and hands the result to a callback — with zero runtime dependencies, dual ESM + CommonJS, and TypeScript types built in.
The original has ~159M downloads/month and no release since December 2018. It still pulls readable-stream, inherits, buffer-from and typedarray — four polyfills that only ever mattered for legacy and browser runtimes. On any supported Node they are dead weight, and they drag transitive-dependency audit noise (#64) along with them. This fork keeps the concatenation logic byte-for-byte identical (verified against the original's own test suite) and drops every dependency.
npm install @bybrave/concat-stream2// CommonJS — drop-in
const concat = require('@bybrave/concat-stream2');
// ESM — default or named import
import concat from '@bybrave/concat-stream2';
import { concat } from '@bybrave/concat-stream2';
// TypeScript types built in — no @types/concat-stream neededUsage
Exactly the same API as the original. Pass an optional options object and a callback; write data; the callback fires on finish with everything concatenated.
const concat = require('@bybrave/concat-stream2');
const fs = require('fs');
const write = concat({ encoding: 'string' }, (data) => {
console.log(data);
});
fs.createReadStream('cat.png').pipe(write);encoding decides the shape of the value handed to your callback. When omitted it is inferred from the first chunk written.
| encoding | Callback receives |
|---|---|
| 'buffer' (or inferred from a Buffer) | a Buffer |
| 'string' | a string |
| 'array' | a flat Array |
| 'uint8array' (aliases 'u8', 'uint8') | a Uint8Array |
| 'object' | an Array of the written objects |
Why this fork
| Fixed / improved | Original issue |
|---|---|
| Zero runtime dependencies — readable-stream, inherits, buffer-from, typedarray replaced with native node:stream, class/util.inherits, Buffer.from, Uint8Array | #69 |
| No more transitive-dependency audit alerts — the whole dependency chain is gone | #64 |
| No Buffer() deprecation warnings — modern Buffer.from / zero-filled Uint8Array throughout | #58, #57, #56, #55 |
| Dual ESM + CommonJS — import and require both work, from one implementation | — |
| Built-in TypeScript types — replaces the separate @types/concat-stream package | — |
The core concatenation algorithm (getBody, inferEncoding, and the per-encoding concatenators) is unchanged from the original and gated by a byte-for-byte golden test that runs the original and the fork over the same inputs.
Migration
Drop-in for the overwhelming majority of uses — change the dependency name and you're done:
- const concat = require('concat-stream');
+ const concat = require('@bybrave/concat-stream2');- "concat-stream": "^2.0.0",
- "@types/concat-stream": "^2.0.0",
+ "@bybrave/concat-stream2": "^3.0.0",Remove @types/concat-stream — the types ship with this package.
Requires Node.js >= 18. If you need to run on legacy Node or bundle for old browsers, stay on the original concat-stream; that's exactly the environment its polyfills existed for.
Error handling (by design)
concat-stream is not a transform stream and intentionally does not forward upstream errors (#50, #37). The callback receives only the concatenated data — cb(data), not cb(err, data). Handle source errors on the pipeline, as you always did:
source.on('error', handleError);
source.pipe(concat(onData));This behaviour is preserved deliberately for drop-in compatibility. If you specifically want error propagation, use a pipeline: stream.pipeline(source, concat(onData), done).
Native alternative
If you only target modern Node and don't need drop-in compatibility with packages that already depend on concat-stream, the built-in stream/consumers covers the common cases directly (#68):
const consumers = require('node:stream/consumers');
const buf = await consumers.buffer(source);
const text = await consumers.text(source);This fork exists for the millions of dependents that use the concat-stream API and want it maintained, dependency-free, and typed.
Support
If this package saves you time, you can support maintenance:
Bitcoin (BTC): bc1q37557q5jpeaxqydzwvf3jgj7zhnfpn2td3q40q
License
MIT. Copyright (c) 2013 Max Ogden (original concat-stream), copyright (c) 2026 bybrave (fork). See LICENSE.
