streamfu
Streams should feel like arrays. Now they do.
Functional stream utilities for JavaScript & TypeScript.
Built on Web Streams. Works everywhere.
$ deno add -D @sgmonda/streamfu
Quick Example
import { createReadable, filter, map, pipe, reduce } from "@sgmonda/streamfu"
const numbers = createReadable([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
const stream = pipe(
numbers,
(r) => filter(r, (n) => n % 2 === 0),
(r) => map(r, (n) => n * 2),
)
const result = await reduce(stream, (a, b) => a + b, 0) // 60
Why streamfu?
Native Web Streams are powerful but painful. Manual reader management, mutable state, while (true) loops — even for simple tasks. streamfu gives you the same power with a clean, functional API.
If you know Array.prototype, you already know streamfu.
| Task | Native Streams | streamfu |
|---|---|---|
| Transform each chunk | pipeThrough(new TransformStream({...})) |
map(stream, fn) |
| Filter chunks | Manual reader loop + condition | filter(stream, fn) |
| Reduce to value | Manual reader loop + accumulator | reduce(stream, fn, init) |
| Combine streams | Manual reader orchestration | zip(s1, s2, s3) |
| Concatenate streams | Complex async pull logic | concat(s1, s2, s3) |
| Split stream | Nested .tee() chains |
branch(stream, n) |
| Get element at index | Manual counter + reader | at(stream, i) |
| Check if value exists | Manual loop + early exit | includes(stream, val) |
| Chain operations | Deeply nested pipeThrough |
pipe(stream, f1, f2, f3) |
Design Principles
Functional & Pure
No side effects, no mutations. Every operation returns a new stream.
Familiar API
Mirrors Array.prototype methods. If you know arrays, you know streamfu.
Universal
Built on the Web Streams API. Works on Node.js, Deno, Bun, browsers, and Cloudflare Workers.
Type-safe
Full TypeScript support with precise generics and type inference through chains.
100% Tested
Every function, every edge case. Coverage enforced in CI.