What is the difference between stream.pipe and stream.pipeline?
pipe connects streams but does not forward errors or clean up, so a failure can leave streams open. pipeline connects several streams, destroys all of them on error, and reports the result in one callback or promise.
Explain it simply
Imagine joining three pipes with plain tape. If the middle pipe bursts, water leaks and the other two keep running. pipeline is like fitting the pipes with a master switch: if any part fails, everything shuts down and you are told once.
Example
const fs = require("fs");
const zlib = require("zlib");
const { pipeline } = require("stream/promises");
// pipe: you must listen for errors on every stream yourself
fs.createReadStream("in.txt")
.pipe(zlib.createGzip())
.pipe(fs.createWriteStream("out.gz"));
// pipeline: one place for errors, automatic cleanup
async function compress() {
try {
await pipeline(
fs.createReadStream("in.txt"),
zlib.createGzip(),
fs.createWriteStream("out.gz")
);
console.log("done");
} catch (err) {
console.error("failed:", err.message);
}
}
compress();With plain pipe, if the source errors, the destination is not closed, which can leak file descriptors. An error on the destination does not stop the source either.
Since Node 15 there is a promise version in stream/promises, which fits naturally with await.
What to say in the interview
"pipe does flow control but no error propagation or cleanup. pipeline handles both, destroying every stream on failure and returning a promise or callback, so I use pipeline in production code."
Common mistakes
- Attaching an
errorhandler only to the last stream in apipechain. - Forgetting that an unhandled
errorevent crashes the process.