Node.jsadvanced
import { createReadStream, createWriteStream } from "node:fs";
import { finished } from "node:stream/promises";
export const copyWithCleanup = async (src: string, dest: string, signal?: AbortSignal) => {
const read = createReadStream(src);
Wait for a stream to finish and clean up resources without ad-hoc listeners.
Node.jsadvanced
import { createReadStream } from "node:fs";
import { Readable } from "node:stream";
export const compressedFileResponse = (path: string) => {
const nodeStream = createReadStream(path, { highWaterMark: 64 * 1024 });
Turn a Node Readable into a web-compatible stream with Readable.toWeb().
Node.jsintermediate
import { Readable } from "node:stream";
async function* paginatedResults(pageCount: number) {
for (let page = 1; page <= pageCount; page++) {
await new Promise((resolve) => setTimeout(resolve, 10)); // simulate a network call
Readable.from() wraps any (async) generator or iterable in a real Readable stream, so it can be piped anywhere a stream is expected.
Bunadvanced
const proc = Bun.spawn(["bun", "-e", "console.log((await Bun.stdin.text()).toUpperCase())"], {
stdin: "pipe",
});
proc.stdin.write("hello from the parent\n");
Bun.spawn's stdin/stdout are a FileSink and a ReadableStream, so you can write to a child process incrementally and read its output as it streams back.
Node.jsadvanced
import type { Writable } from "node:stream";
export const streamJsonArray = async (rows: AsyncIterable<unknown>, out: Writable) => {
out.write("[");
let first = true;
Write a large JSON array to a stream item by item as it's produced, instead of building the whole array in memory before calling JSON.stringify.
Node.jsadvanced
import { createReadStream, createWriteStream } from "node:fs";
import { pipeline } from "node:stream/promises";
import { Transform } from "node:stream";
const upperCaseChunks = new Transform({
Use stream/promises pipeline() to move data through a Transform without ever buffering more than the stream can hold.