I published @hsblabs/web-stream-extras.
It started as internal plumbing I kept copy-pasting across projects. Enough utility collected around ReadableStream<Uint8Array> that it made sense to package it properly.
npm install @hsblabs/web-stream-extras
Node.js ≥22 and modern browsers. No runtime dependencies.
What's in the root package
The root export handles the everyday byte stream operations.
import {
readableFromChunks,
readAllBytes,
stringToBinary,
binaryToString,
} from "@hsblabs/web-stream-extras";
const stream = readableFromChunks([
stringToBinary("hello"),
stringToBinary(" world"),
]);
const result = await readAllBytes(stream);
console.log(binaryToString(result)); // "hello world"
readableFromChunks wraps an array of Uint8Array chunks into a proper ReadableStream. readAllBytes collects everything from a stream into a single Uint8Array. The string and buffer conversion helpers — stringToBinary, binaryToString, toU8Array, toArrayBuffer, concatU8Arrays — exist because converting between string, Uint8Array, and ArrayBuffer is repetitive and easy to get subtly wrong.
ByteTransformStream is an abstract base for building typed binary transform pipelines. ByteQueue handles internal buffering with a clean read/write interface — useful when you need to track partial byte reads across chunks.
Base64url encoding is included too: encodeBase64Url and decodeBase64Url, without padding.
Stream encryption
The encryption subpath adds encryption built on the Web Crypto API.
import {
encryptStream,
decryptStream,
} from "@hsblabs/web-stream-extras/encryption";
const key = crypto.getRandomValues(new Uint8Array(32));
const encrypted = encryptStream(key, plaintext);
const decrypted = decryptStream(key, encrypted);
encryptStream and decryptStream take a ReadableStream and return a ReadableStream. The underlying EncryptionStream and DecryptionStream are exposed as TransformStream wrappers if you need to compose them differently.
For cases where you need key management, webCryptoStream(masterKey) handles deriving and encrypting per-stream keys with an AES-GCM master key.
Why Web Streams
The WHATWG Streams API is available natively in Node.js ≥18 and all modern browsers. Using it directly avoids Node.js-specific stream abstractions and keeps the code portable. If you're targeting environments where both sides — browser and server — need to handle the same byte pipeline, the WHATWG API is the right base layer.
Issues and feedback welcome.
Top comments (0)