Skip to main content

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:

javascript
readable .pipe(transform) .pipe(writable);

But that approach has drawbacks:

  • if one stream throws an error, the others don't close;
  • destroy() or end() has to be called manually;
  • it's hard to tell when the entire chain has finished.

pipeline() fixes all of that.

Syntax

javascript
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

javascript
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:

javascript
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

javascript
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 doesDescription
Chains streamsWorks like pipe(), but safer
Catches errorsAutomatically destroys every stream on error
Waits for completionThe callback/promise fires once everything is fully done
Works with any typeReadable, Writable, Transform, Duplex

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.