Implementing Custom Transform Streams with _transform and _flush
Build reusable Transform streams that mutate, filter, and aggregate chunks as data flows through them.
Why Transform Streams?
A Transform stream is both readable and writable: it consumes input chunks, processes them, and pushes output chunks. It is the right tool whenever data must be mutated as it flows rather than buffered fully in memory.
- Writable side accepts data via
write()/pipe()from upstream. - Readable side emits processed data that downstream consumers read.
Typical backend uses: uppercasing/normalizing a payload, gzip-style encoding, CSV-to-JSON conversion, redacting secrets in a log pipeline, or counting bytes — all without loading the whole file or HTTP body into RAM.
The Two Hooks: _transform and _flush
A custom Transform stream is defined by implementing two internal methods. Node calls them for you — you never call them directly.
_transform(chunk, encoding, callback)— invoked once per incoming chunk. Do your work,push()any output, then signal completion withcallback()._flush(callback)— invoked once, after the last chunk, just before the stream ends. Use it to emit any trailing/aggregated data.
The leading underscore marks them as the framework-facing implementation. Consumers still use the public write, read, and pipe API.
All lessons in this course
- Readable, Writable, Duplex & Transform Stream Internals
- Implementing Custom Transform Streams with _transform and _flush
- Backpressure, pipe() and the pipeline() Utility
- Async Iterators and for-await-of Over Streams