What does pipeline() do in the stream module?
The pipeline() function from Node.js's stream module is a convenient, safe way to chain several streams (Readable, Writable, Transform) together, with automatic error handling and completion tracking.
The problem pipeline() solves
Developers used to chain streams by hand, like this:
readable
.pipe(transform)
.pipe(writable);But that approach has drawbacks:
- if one stream throws an error, the others don't close;
destroy()orend()has to be called manually;- it's hard to tell when the entire chain has finished.
pipeline() fixes all of that.
Syntax
const { pipeline } = require('stream');
pipeline(
source, // Readable
transform1, // Transform (optional)
transform2, // Transform (optional)
destination, // Writable
(err) => { // the callback runs on completion or error
if (err) {
console.error('Stream error:', err);
} else {
console.log('The streams finished successfully');
}
}
);An example
const fs = require('fs');
const zlib = require('zlib');
const { pipeline } = require('stream');
pipeline(
fs.createReadStream('input.txt'),
zlib.createGzip(),
fs.createWriteStream('input.txt.gz'),
(err) => {
if (err) {
console.error('Compression error:', err);
} else {
console.log('The file was compressed successfully!');
}
}
);Here:
fs.createReadStream()is the Readable Stream (reads the file),zlib.createGzip()is the Transform Stream (compresses the data),fs.createWriteStream()is the Writable Stream (writes the result),pipeline()connects them and manages the whole process.
Advantages of pipeline()
Automatic error handling
If any stream throws an error, every other one closes correctly (destroy() is called automatically).
Convenient completion notification The final callback fires once every stream has finished (or an error happened).
Async support
Since Node.js 15, pipeline() is also available in a promise-based form:
const { pipeline } = require('stream/promises');
await pipeline(
fs.createReadStream('input.txt'),
zlib.createGzip(),
fs.createWriteStream('input.txt.gz')
);
console.log('Compression finished!');Using it with async/await
import { pipeline } from 'stream/promises';
import fs from 'fs';
import zlib from 'zlib';
async function compress() {
try {
await pipeline(
fs.createReadStream('data.txt'),
zlib.createGzip(),
fs.createWriteStream('data.txt.gz')
);
console.log('The file was compressed with no errors!');
} catch (err) {
console.error('Error:', err);
}
}
compress();When to use pipeline()
Use pipeline() when:
- you have several streams chained together (
Readable → Transform → Writable); - you want reliable error handling;
- you're working with the Promise API (
await pipeline()).
If you only have one or two streams, plain .pipe() is enough.
In short
| What it does | Description |
|---|---|
| Chains streams | Works like pipe(), but safer |
| Catches errors | Automatically destroys every stream on error |
| Waits for completion | The callback/promise fires once everything is fully done |
| Works with any type | Readable, Writable, Transform, Duplex |
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.