A modern polyfill for node:stream.
This package replaces readable-stream in ZenFS. readable-stream made up 10 of the 17 dependencies in the @zenfs/core tree and totaled 703 KB unpacked, and it has a number of unresolved problems with its types and legacy code.
It is written in TypeScript against Node's current implementation, and every exported class is declared implements its node:stream counterpart.
import { Readable, Writable, pipeline } from '@zenfs/streams';
await pipeline(
Readable.from(['hello', ' ', 'world']),
new Writable({
write(chunk, encoding, callback) {
console.log(chunk.toString());
callback();
},
})
);- The only runtime dependency is
buffer, which resolves to the built-in module on Node.events,process,abort-controllerandstring_decoderare not needed:EventEmitterandStringDecoderare implemented here, andAbortControllerandqueueMicrotaskare used directly. StringDecoderdecodes UTF-8 with a streamingTextDecoder. UTF-16LE is handled separately, since Node drops a trailing odd byte and preserves lone surrogates where the WHATWG decoder replaces both with U+FFFD.- Outside Node there is no
process.nextTick, so callbacks fall back toqueueMicrotask. Node drains its next-tick queue ahead of the microtask queue; the fallback has no equivalent, so those callbacks interleave with promise continuations rather than preceding them. finished()on a WHATWG stream needs the closed-promise symbol thatnode:stream(and this package'stoWeb()) attaches. A plainReadableStreamcannot be observed without consuming it, so it is rejected.setMaxListenersis honored as state but never produces Node'sMaxListenersExceededWarning.