Skip to solution
easyPhone Screen

What are stream piping and the .pipe() method in Node.js?

978 views
01

Understand the problem

Question presented to candidate: "You need to copy data from a readable source directly to a writable destination — a file to an HTTP response, for instance. What does .pipe() actually do, and why not just manually forward each chunk yourself?"

What a strong answer should cover:

  • .pipe() connects a Readable stream's output directly to a Writable stream's input: every chunk the readable produces is automatically written to the writable, without manually wiring up 'data' event listeners and calling .write() yourself.
  • 📌 It automatically handles backpressure: if the destination writable is slower than the source readable, .pipe() automatically pauses reading from the source until the destination signals it can accept more — manually forwarding 'data' events yourself does not do this for free.
  • stream.pipe() returns the destination stream, which is what enables chaining: source.pipe(transform1).pipe(transform2).pipe(destination), passing data through successive transform steps.
  • .pipe()'s well-known limitation, covered fully in its own dedicated question, is incomplete error propagation and cleanup: an error on the source does not automatically destroy the destination, which can leak open file handles/sockets — stream.pipeline() (Node's modern replacement) fixes exactly this.
  • A concrete, common real-world use: fs.createReadStream(path).pipe(res) inside an HTTP handler streams a file directly to the client without ever loading the whole file into memory — connecting the file-system-read question and the readFile-vs-createReadStream question to this one.
  • A precise answer names .pipe() as the original, still-common mechanism, while pointing to stream.pipeline() as the currently recommended choice for anything beyond the simplest, single-hop, already-correctly-error-handled case.

Clarifying questions expected:

  • "Is proper error handling and cleanup across the whole chain a requirement here?" — if so, stream.pipeline() is the better answer than raw .pipe().
  • "Is this a single hop (source to destination) or a multi-step transform chain?" — .pipe()'s chaining return value matters more for the latter.

Code / implementation expected: Yes — a real, working .pipe() call actually delivering data end to end is the concrete, convincing part of the answer.

streamsfile-systempipes
02

Attempt it yourself

Sketch your approach before reading the solution — that's what interviews test.

Nudge consolestandby

Stuck? Beam a request up — the console returns a conceptual nudge that guides your logic without spoiling the implementation.

03

Study the solution

Target Audience: Engineers preparing for Node.js phone screens — assumes very basic stream familiarity. Difficulty: Easy

How to read this doc: Concepts are explained in plain language first, then tagged with 📌 Interview term:. The pipe below was actually run on Node v24.19.0, delivering

Solution ready — 2 min read

Classified // press E to declassify

04

Read the code

A real .pipe() call delivering exact source data to a custom destination, end to end
const { Readable, Writable } = require("stream");

const src = Readable.from(["chunk1-", "chunk2-", "chunk3"]);
let received = "";
const dest = new Writable({
  write(chunk, enc, cb) {
    received += chunk;
    cb(); // signals "ready for the next chunk" — this is what enables backpressure
  },
});

src.pipe(dest);
dest.on("finish", () => console.log("received via pipe:", received));
// received via pipe: chunk1-chunk2-chunk3

// A common real use — streaming a file directly to an HTTP response:
// fs.createReadStream("./large-file.zip").pipe(res);
05

Join the discussion

Discussion (0)

Sign in to join the discussion.

No responses yet. Be the first to share what you think.

Transmission complete // awaiting log

KEEP THE
STREAK ALIVE.

Dossier 6 of 152 decoded in the Node.js track. One more won't hurt.

Back to track