npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

llm-stream-mux

v1.1.0

Published

Zero-dependency TypeScript stream orchestration for LLM pipelines — race, fallback, merge, and tee over any AsyncIterable or ReadableStream, generic over T.

Readme

llm-stream-mux

version node runtime deps status ci

Race, fallback, merge, and tee over any stream — generic over T, zero runtime dependencies, Web Streams throughout.

A standalone TypeScript stream-orchestration layer for LLM pipelines: coordinate multiple AsyncIterable<T> or ReadableStream<T> sources with race, fallback, ensemble/merge, and bounded tee — raw bytes or parsed events, with no baked-in event model.

Orchestrate streams — not another hand-rolled Promise.race on fetch.

Status: 1.1.0 — stable; §9 runtime exports and §6.3 MuxErrorCode frozen as of 1.0.0 under semver. 972 tests via pnpm verify. Spec: docs/proposal.MD · stability: docs/STABILITY.md · security: SECURITY.md


Contents


Positioning

llm-stream-mux is the N↔1 orchestration layer only: race, fallback, merge, and tee over streams you already opened. You keep your HTTP client, auth, parsing (llm-stream-assemble), security filters, and UI.

Ecosystem: assemble · guard · mux

| Library | Shape | Responsibility | | ---------------------------------------------------------------------- | ----- | ----------------------------------------------------- | | llm-stream-assemble | 1→1 | Parse one provider stream → typed events (format) | | llm-stream-guard | 1→1 | Redact / tool policy (safety) | | llm-stream-mux | N↔1 | Race, fallback, merge, tee (orchestration) |

No npm coupling between the three — compose in userland (cookbook).


Why not hand-roll?

Multi-stream coordination fails in production for predictable reasons:

  • Promise.race on fetch does not cancel losing HTTP bodies or buffer pre-usable frames.
  • Native ReadableStream.tee() grows memory without bound when one branch is slow.
  • Failover after partial output splices two responses unless you define a commit point.
  • Naïve merge loops drop settled reads when using Promise.race on pending iterators.

Concrete contracts and test IDs: docs/edge-cases.md.


Edge-case showcase

Three orchestration footguns mux addresses by design:

Strategies overview

  • Unbounded tee() → mux tee with block / bounded / drop.
  • Junk-first race winnerisUsable + ordered pre-usable buffer flush.
  • Merge read loss → one pending read per source; re-arm after consume.

Walkthrough: docs/edge-cases.md.


Why use this

  • Zero runtime dependencies.
  • Generic over TUint8Array byte mode or any parsed event type.
  • Four strategies with semantic hooks (isError, isUsable, isFinal, mapEach).
  • ObservableonSourceEvent, MuxResult, stable MuxError codes.
  • Runtime-agnostic — Node 22+, Bun, Deno, Cloudflare Workers (Web Streams only).

Install

npm install llm-stream-mux
# or: pnpm add llm-stream-mux

Pin: npm install [email protected]. Public API frozen at 1.0.0 (STABILITY).

Requirements: Node.js 22+ · see compatibility matrix.


Quickstart

Byte mode — race two provider bodies

import { race } from "llm-stream-mux";

const winner = race<Uint8Array>([resA.body!, resB.body!], { signal, timeoutMs: 5000 });

for await (const chunk of winner) {
	// first usable stream wins; losers cancelled
}

Event mode — merge tagged outputs

import { merge } from "llm-stream-mux";

for await (const tagged of merge<MyEvent>(
	{ gpt: streamA, claude: streamB },
	{
		isError: (e) => e.type === "error",
		onSourceEvent: (s) => log(s),
	},
)) {
	if (tagged.kind === "value") render(tagged.source, tagged.value);
}

Strategy picker: docs/usage-guides.md · quick-decision diagram.


Architecture

End-to-end pipeline


Strategies at a glance

| Function | Shape | Use when | | -------------------- | ----- | ----------------------------------------------- | | race(sources) | N→1 | Fastest usable stream wins; cancel losers | | fallback(sources) | N→1 | Primary → backup; lazy thunks for true failover | | merge / ensemble | N→1 | Parallel models; Tagged<T> per source | | tee(source, n) | 1→N | Fan-out with bounded backpressure |

Helpers: collect, toReadable, toAsyncIterable.

Full API: proposal §9.


Documentation


Examples

Runnable samples: examples/node-fetch/race.ts, fallback.ts, merge.ts, tee.ts (fake streams; pnpm typecheck:examples after build).

For parsing examples see llm-stream-assemble/examples.


Non-goals

  • No HTTP client, auth, or retry of the same request.
  • No provider parsing (assemble).
  • No content redaction / tool policy (guard).
  • No UI, agent loop, or tool execution.

Development

./scripts/setup-githooks.sh   # once per clone — strip AI co-author trailers
pnpm install
pnpm verify

CI runs pnpm verify on Node 22 and 24; smoke-runtimes.yml smoke-tests Bun + Deno.

| Command | Description | | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | pnpm verify | portability + deps + lint + typecheck + build + test + smoke + docs + diagrams + format | | pnpm build | tsup → ESM + CJS + declarations in dist/ | | pnpm test | Vitest — LSM-REL-*, LSM-TYP-*, LSM-CORE-*, LSM-TEE-*, LSM-RACE-*, LSM-FB-*, LSM-MERGE-*, LSM-X-*, LSM-EDGE-*, LSM-EDGE-P0-*, LSM-SRC-* | | pnpm verify:portability | forbid Node-only / ReadableStream.from patterns in src/ | | pnpm smoke:package | ESM/CJS import from npm pack tarball | | pnpm smoke:runtimes | Node (+ optional Bun/Deno) tarball smoke — --skip-optional locally, --ci in Actions | | pnpm smoke:consumer | ESM + CJS downstream consumer smoke from tarball | | pnpm smoke:published | post-pack publish simulation (--node22 / --node24 / --all-runtimes) | | pnpm verify:pre1 | maintainer gate: verify + release:prep + smoke:runtimes + smoke:consumer + smoke:published | | pnpm verify:deps | fail if runtime dependencies added | | pnpm diagrams:build | render docs/img/*.mmd.svg | | pnpm diagrams:check | SVGs present and newer than .mmd | | pnpm typecheck:examples | Typecheck examples/ against built dist/ | | pnpm release:prep | pre-tag checks (version, CHANGELOG, npm pack, examples) |


Author

Ladislav Kostolny[email protected] · GitHub @01laky

License

MIT — see LICENSE. Copyright (c) 2026 Ladislav Kostolny.