NelsonLabs

Streams

Streams process data in chunks rather than loading everything into memory at once. They're how Node.js efficiently handles large files, video streams, real-time data, and network responses.

ANALOGY

A water pipe, not a bucket. Copying a 10GB file using a bucket means loading all 10GB into memory, then pouring it out. A pipe moves the water continuously — you never hold it all at once. Streams work the same way. They're how Node.js processes a 10GB log file without running out of memory.

Readable and writable streams
javascript
const fs   = require("fs");
const path = require("path");

// Read a file as a stream
const readStream = fs.createReadStream("large-file.csv", {
  encoding: "utf8",
  highWaterMark: 64 * 1024,  // 64KB chunks
});

readStream.on("data", chunk => {
  console.log("Received chunk:", chunk.length, "bytes");
});

readStream.on("end",  ()    => console.log("File read complete"));
readStream.on("error", err  => console.error("Error:", err));

// Write a file as a stream
const writeStream = fs.createWriteStream("output.txt");
writeStream.write("Line 1
");
writeStream.write("Line 2
");
writeStream.end("Final line
");
Piping — the most common stream pattern
javascript
const fs   = require("fs");
const zlib = require("zlib");

// Compress a file — pipe readable through gzip into writable
fs.createReadStream("data.txt")
  .pipe(zlib.createGzip())
  .pipe(fs.createWriteStream("data.txt.gz"));

// Serve a large file from an HTTP server without loading it all into RAM
const http = require("http");
http.createServer((req, res) => {
  res.writeHead(200, { "Content-Type": "video/mp4" });
  fs.createReadStream("video.mp4").pipe(res);
}).listen(3000);