The Codex / JavaScript / streams — Streams

streams — Streams

Processing data incrementally in Node.js — Readable, Writable, Transform streams, pipeline, and async iteration.

What it is, in plain English: Streams are Node.js's way of processing data piece by piece, without loading the whole thing into memory. A Readable stream produces data. A Writable stream consumes data. A Transform stream does both — it receives data, transforms it, and outputs the result. pipeline() connects streams together and handles errors and cleanup. Streams implement the async iterable protocol — you can use for await...of.

Why streams — memory-efficient data processing

Without streams, to process a large file you load it all into memory. A 10GB log file would need 10GB of RAM. Streams process data in small chunks — the same task uses only kilobytes of memory.

The four stream types

// Readable  — source of data
// Writable  — destination for data
// Transform — reads, transforms, writes (both ends)
// Duplex    — separate read and write (like a TCP socket)

// You use streams constantly without realising it:
process.stdin;                      // Readable
process.stdout;                     // Writable
fs.createReadStream("file.txt");    // Readable
fs.createWriteStream("out.txt");    // Writable
zlib.createGzip();                  // Transform
http.IncomingMessage;               // Readable (req in createServer)
http.ServerResponse;                // Writable (res in createServer)

Reading a stream with async iteration

import { createReadStream } from "fs";
import { createInterface }  from "readline";

// Read a large file line by line (memory-efficient):
const rl = createInterface({
  input:     createReadStream("large.csv"),
  crlfDelay: Infinity,
});

let lineNumber = 0;
for await (const line of rl) {
  lineNumber++;
  if (lineNumber === 1) continue;  // skip header
  processRow(line.split(","));
}
console.log(`Processed ${lineNumber} lines`);

pipeline — the correct way to connect streams

import { createReadStream, createWriteStream } from "fs";
import { createGzip } from "zlib";
import { pipeline }   from "stream/promises";

// Compress a file:
await pipeline(
  createReadStream("big-file.json"),   // read
  createGzip(),                         // compress
  createWriteStream("big-file.json.gz") // write
);
// pipeline: handles backpressure, errors, and cleanup automatically

// ✗ Don't use .pipe() directly — it doesn't handle errors:
// readStream.pipe(gzip).pipe(writeStream);  // if gzip fails, streams don't close!
Try It Yourself

Official Sources

The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.