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

brass-runtime

v1.21.0

Published

Effect runtime utilities for TypeScript

Downloads

3,045

Readme

brass-runtime

A ZIO-inspired effect runtime for TypeScript with structured concurrency, runtime diagnostics, pull-based streams, and a production-grade HTTP client.

Built without Promise/async/await as the primary semantic primitive. Effects are values — lazy, composable, and cancelable by default.

npm i brass-runtime

Runnable framework examples live in the repository examples. They are kept out of the npm package so installs stay small.


What it does

Runtime — algebraic effects, fibers, scopes, scheduler, interruptibility regions, fiber-local refs, typed layers, semaphores, circuit breakers, rich Cause<E> failures, metrics, tracing, and an opt-in flight recorder.

Streams — pull-based streams with backpressure, bounded buffers, hubs, pipelines, fusion optimization, and a small fluent DX facade.

HTTP — lazy/cancelable client and server primitives with typed routing, schema validation, health/readiness probes, adaptive concurrency, compression, batching, prewarm, cache, dedup, priority, retry, and observability.

Production signals — dependency-free schemas, Prometheus/OTLP exporters, structured logs, W3C trace propagation, sampling, redaction, bounded exporters, and explicit flush/shutdown.

Performance profiler — runtime primitives, HTTP layer comparison, memory retention reports, observability overhead, CLI/JSON output, and actionable recommendations.

Optional engine and tools — Rust/WASM-backed state machines plus the experimental Brass Agent CLI/VS Code workflow.


Philosophy

  • Effects are values — lazy, composable, referentially transparent
  • Async is explicit — no hidden Promise semantics
  • Concurrency is structured — fibers, scopes, finalizers
  • Side effects are interpreted — not executed eagerly
  • Higher-level APIs are libraries — HTTP, streams, agent are built on top of core

Quick start

Run an effect

import { runPromise, succeed } from "brass-runtime";

const value = await runPromise(succeed(42));

Use makeRuntime when you want explicit runtime options, and runExit when you want the full Exit/Cause instead of a rejected promise.

Inspect failure causes

import { Cause, formatCause } from "brass-runtime";

const cause = Cause.then(
  Cause.fail("database unavailable"),
  Cause.both(Cause.interrupt(), Cause.die(new Error("release failed"))),
);

console.log(formatCause(cause));

Cause<E> preserves typed failures, defects, interruptions, and sequential or parallel composition (Then / Both) so diagnostics can explain what happened without flattening every failure into a single thrown value.

Mask interruption

import { async, flatMap, succeed, uninterruptibleMask } from "brass-runtime";

const effect = uninterruptibleMask((restore) =>
  flatMap(succeed("acquired"), (resource) =>
    restore(async((_env, cb) => {
      setTimeout(() => cb({ _tag: "Success", value: `used:${resource}` }), 10);
    })),
  ),
);

Use uninterruptible(effect) for critical regions and uninterruptibleMask((restore) => ...) when only part of the region should be interruptible again. Pending interruption is deferred until the protected region exits; restored sub-effects remain cancelable.

Fiber-local context

import { Runtime, makeFiberRef } from "brass-runtime";

const requestId = makeFiberRef("anonymous");
const runtime = Runtime.make({});

const result = await runtime.toPromise(
  requestId.locally("req-123", requestId.get()),
);

FiberRef values are local to the running fiber, inherited by child fibers at fork time, isolated from child mutations, and restored after locally regions even when the region fails or is interrupted.

Explain runtime behavior

import { Runtime, async, makeRuntimeRecorder } from "brass-runtime";

const recorder = makeRuntimeRecorder({ maxEvents: 5000 });
const runtime = new Runtime({ env: {}, hooks: recorder.hooks });

await runtime.toPromise(async((_env, cb) => {
  setTimeout(() => cb({ _tag: "Success", value: "ok" }), 10);
}));

console.log(recorder.explain());

The flight recorder is opt-in and keeps a bounded ring buffer of runtime events: fiber start/end/suspend/resume, scopes, supervisor events, logs, spans, and trace context when available.

Recommended HTTP client

import { makeDefaultHttpClient, s } from "brass-runtime/http";

const User = s.object({
  id: s.number({ int: true }),
  name: s.string({ minLength: 1 }),
  role: s.enum(["admin", "user"] as const).optional(),
});

const http = makeDefaultHttpClient({
  baseUrl: "https://api.example.com",
  headers: { accept: "application/json" },
});

const user = await http.getJson("/users/1", { schema: User }).unsafeRunPromise();

console.log(user.body.name);
console.log(http.stats());
console.log(http.compression?.stats());

makeDefaultHttpClient is the batteries-included entrypoint: timeout, deduplication, priority scheduling, retry, adaptive concurrency, safe-method response cache, decompression, stats, cancelAll, and JSON/text helpers. Use preset: "production" when you want that production-ready shape explicitly, preset: "balanced" to skip the default cache, preset: "highThroughputProxy" for hot BFF/proxy paths without lifecycle queues or Brass timers by default, preset: "proxy" as the shorter compatibility alias, or preset: "minimal" for a cheap wire client with the same helper API. preset: "default" remains the same full preset for compatibility.

On Node BFF/proxy services, pair the proxy preset with the first-party node:http transport when the default fetch backend is the bottleneck. The Node-only factory below wires that recommended shape directly:

import { toPromise } from "brass-runtime";
import { makeNodeHttpProxyClient } from "brass-runtime/http";

const http = makeNodeHttpProxyClient({
  baseUrl: "https://api.example.com",
  nodeTransport: {
    maxSockets: 512,
    maxFreeSockets: 512,
  },
});

await toPromise(http.shutdown(), {}); // also destroys owned Node agents

The HTTP stack is meant to replace the usual fetch wrapper plus Zod/Valibot glue: schemas are dependency-free, responses and request bodies are validated in the same effect, config validation fails at construction time, and the client still owns cancellation, retries, compression, observability, and adaptive limits as one pipeline.

Custom Promise clients such as Axios can be injected without making the consumer manage AbortSignal or Async plumbing:

import {
  defineHttpPolicyPresets,
  formatHttpError,
  isRetryableHttpError,
  makeDefaultHttpClient,
  promiseHttpTransport,
} from "brass-runtime/http";

const transport = promiseHttpTransport()
  .requestConfig(({ request, url }) => ({
    url: url.toString(),
    method: request.method,
    headers: request.headers,
    data: request.body,
    responseType: "json",
  }))
  .send((config) => axiosInstance.request(config))
  .json();

const axiosHttp = makeDefaultHttpClient({
  baseUrl: "https://api.example.com",
  transport,
});

try {
  await axiosHttp.getJson("/users/1").unsafeRunPromise();
} catch (error) {
  if (isRetryableHttpError(error)) {
    console.warn("transient upstream failure");
  }
  console.error(formatHttpError(error));
}

Brass injects the runtime AbortSignal into object configs before send and normalizes external failures with toHttpError, including Axios-like response.status, aborts, and common timeout codes.

Repeated execution intent can be named once with policy presets:

const policies = defineHttpPolicyPresets({
  readModel: {
    lane: "read-model",
    poolKey: "users-api",
    priority: 2,
    retry: { maxRetries: 2, baseDelayMs: 50 },
  },
});

const http = makeDefaultHttpClient({
  baseUrl: "https://api.example.com",
  policyPresets: policies,
});

await http.getJson("/users/1", {
  policy: { preset: "readModel", dedupKey: "users:1" },
}).unsafeRunPromise();

The default adaptive limiter uses the aggressive preset: warmup sample floor, P5 baseline, error-rate signal, priority-aware queueing, jittered probes, proportional headroom, capped decreases, and TTL-evicted per-key state. Call shutdown() for explicit cleanup.

The same schema DSL is available outside HTTP:

import { Schema } from "brass-runtime/schema";

const Config = Schema.object({
  port: Schema.int({ min: 1 }),
  callbackUrl: Schema.url(),
});

const config = Config.parse({ port: 3000, callbackUrl: "https://example.com/cb" });

Schemas can validate request bodies before the HTTP request is sent:

import { Schema } from "brass-runtime/schema";

const CreateUser = Schema.object({
  name: Schema.string({ minLength: 1 }),
});

await http.postJson(
  "/users",
  { name: "Ada" },
  { bodySchema: CreateUser, schema: User }
).unsafeRunPromise();

The same validation machinery checks runtime, HTTP, and observability configs at construction time, so invalid values fail with field paths like $.otlp.pipeline.batchSize instead of surfacing later as ambiguous behavior.

HTTP server

import { asyncSucceed, asyncSync, runPromise, useResource } from "brass-runtime";
import { HttpServer, s } from "brass-runtime/http";

const User = s.object({
  id: s.nonEmptyString(),
  name: s.nonEmptyString(),
});

const router = HttpServer.router([
  HttpServer.route("GET", "/users/:id", {
    params: s.object({ id: s.nonEmptyString() }),
    response: User,
  }, (ctx) =>
    asyncSucceed(HttpServer.json({
      id: ctx.params.id,
      name: "Ada",
    })),
  ),
  HttpServer.healthRoute(),
  HttpServer.readinessRoute(),
]);

await runPromise(
  useResource(
    router.listen({ port: 3000 }),
    (server) => asyncSync(() => {
      console.log(server.url());
    }),
  ),
);

Routes infer :params from the path, optional schemas validate params/query/body/response, middleware is effect-based, and the Node listener is available as a managed resource for graceful shutdown.

Discoverable HTTP builder

import { httpClientBuilder } from "brass-runtime/http";

declare const token: string;

const http = httpClientBuilder()
  .baseUrl("https://api.example.com")
  .production()
  .balancedLimiter({ maxLimit: 128 })
  .header("authorization", `Bearer ${token}`)
  .cache({ ttlSeconds: 30, maxEntries: 512 })
  .retry({ maxRetries: 2, baseDelayMs: 100, maxDelayMs: 1_000 })
  .build();

HTTP test helpers

import {
  makeJsonHttpResponse,
  makeMockHttpClient,
  runHttpEffect,
} from "brass-runtime/http/testing";

const mock = makeMockHttpClient((req) => makeJsonHttpResponse({ url: req.url }));
const response = await runHttpEffect(mock({ method: "GET", url: "/users/1" }));

Domain-specific layers still fit in the same config:

const http = makeDefaultHttpClient({
  baseUrl: "https://api.example.com",
  batch: {
    windowMs: 50,
    maxBatchSize: 20,
    batchKey: (req) => req.url.startsWith("/graphql") ? "graphql" : "",
    batch: {
      coalesce: (reqs) => ({ method: "POST", url: "/graphql/batch", body: JSON.stringify(reqs) }),
      split: (res, reqs) => JSON.parse(res.bodyText),
    },
  },
});

const response = await http.getJson<User>("/users/1").unsafeRunPromise();

Adaptive concurrency

import { makeAdaptiveLimiterConfig, makeHttp } from "brass-runtime/http";

const http = makeHttp({
  adaptiveLimiter: makeAdaptiveLimiterConfig("balanced", {
    maxLimit: 100,
    stateTtlMs: 300_000,
    warmupRequests: 20,
    minSamples: 25,
    decreaseCooldownSamples: 3,
    decreaseThreshold: 0.6,
    maxDecreaseRatio: 0.15,
    historySize: 64,
    onLimitChange: (event) => console.log(`limit: ${event.previousLimit} → ${event.newLimit}`),
  }),
});

console.log(http.adaptiveLimiter?.dump());
console.log(http.adaptiveLimiter?.history("https://api.example.com"));
http.shutdown?.();

More end-to-end examples live in docs/http-recipes.md.

Connection pre-warming

import { makePrewarmManager } from "brass-runtime/http";

const prewarm = makePrewarmManager({
  origins: ["https://api.example.com", "https://cdn.example.com"],
  keepAliveDurationMs: 55000,
  autoRefresh: true,
});

await prewarm.warmAll();
// Subsequent requests skip TCP+TLS handshake

Response compression

import { makeCompressionMiddleware, makeDefaultHttpClient } from "brass-runtime/http";

const { middleware, stats } = makeCompressionMiddleware({ encodings: ["br", "gzip"] });
const baseClient = makeDefaultHttpClient({
  baseUrl: "https://api.example.com",
  compression: false,
});
const client = baseClient.with(middleware);
// Responses are transparently decompressed (gzip, brotli, deflate)

Production observability

import { Runtime, asyncSucceed } from "brass-runtime/core";
import {
  makeObservability,
  makeOtlpOptions,
  runObservedHttpServerEffect,
  withHttpObservability,
} from "brass-runtime/observability";
import { makeDefaultHttpClient } from "brass-runtime/http";

const obs = makeObservability({
  serviceName: "api",
  logs: { minLevel: "info" },
  sampling: { ratio: 0.25, respectRemoteSampled: true, forceSampleOnError: true },
  redaction: {},
  cardinality: { maxValuesPerLabel: 100 },
  otlp: makeOtlpOptions({ endpoint: "http://collector:4318" }),
  flushIntervalMs: 10_000,
});

const runtime = new Runtime({ env: obs.env, hooks: obs.hooks });
const client = makeDefaultHttpClient({
  baseUrl: "https://api.example.com",
  middleware: [withHttpObservability(obs)],
});

await runObservedHttpServerEffect(
  obs,
  { method: "GET", route: "/users/:id" },
  asyncSucceed("ok")
);
await runtime.toPromise(client.getText("/health"));
await obs.shutdown();

HTTP client observability automatically reads adaptive limiter diagnostics when the wrapped client owns a limiter, exposing gauges for current limit, queue depth, utilization, error rate, request/completion rate, rejection rate, and state count. It also reads req.policy automatically: logs and span attributes include preset, lane, poolKey, dedupKey, priority, and retry overrides when present. Metric labels stay conservative by default; opt into stable labels with withHttpObservability({ policy: { labelKeys: ["preset", "lane", "poolKey"] } }).

For hot proxy paths, keep HTTP metrics separate from runtime hooks: makeObservability({ metrics: false, logs: false, traces: false }), preset: "proxy", withHttpObservability({ spans: false, logs: false, injectTraceHeaders: false, includeHostLabel: false }). For sampled spans on the same path, avoid global runtime hooks and use withHttpObservability({ spans: { events: false, sampleRate: 0.001 }, spanSink: observability.tracer, injectTraceHeaders: false }).

Performance profiler

npm run perf
npm run perf:json
npm run benchmark:perf
npm run perf:runtime:ab
npm run perf:runtime:soak
npm run perf:runtime:budget
npm run perf:http:memory
npm run perf:history
import { runBrassPerformanceProfile } from "brass-runtime/perf";

const report = await runBrassPerformanceProfile({
  http: {
    calls: 20_000,
    concurrency: 512,
    delayMs: 2,
    forceGc: true,
    variants: ["default-json", "default-json-observed"],
  },
});

console.log(report.recommendations);

The profiler compares runtime primitives, runtime A/B variants, runtime-only soak behavior, node:http, Brass wire/default HTTP clients, HTTP long-run memory, observability overhead, history/baseline regressions, and memory deltas. Use docs/performance-profiler.md for focused commands and node --expose-gc runs.

Perf runs can be persisted and compared locally:

npm run perf -- --profile runtime-ab --record-history --save-baseline runtime-main
npm run perf -- --profile runtime-ab --compare-baseline runtime-main --fail-on-baseline-regression

First-release recipes

Copyable happy paths live in docs/recipes:

  • runtime execution
  • typed layers
  • HTTP server
  • testing
  • performance baselines

Structured concurrency

import { Runtime, asyncSucceed, withScope } from "brass-runtime";

const runtime = Runtime.make({});

await runtime.toPromise(
  withScope(runtime, (scope) => {
    scope.fork(asyncSucceed("child"));
    // scope close interrupts children + runs finalizers
  })
);

Streams

import { Runtime, Stream } from "brass-runtime";

const runtime = Runtime.make({});
const result = await Stream
  .from([1, 2, 3, 4, 5])
  .map((n) => n * 2)
  .collect(runtime);
// [2, 4, 6, 8, 10]

Package exports

| Import | Purpose | |--------|---------| | brass-runtime | Core runtime: effects, fibers, scheduler, streams, layers | | brass-runtime/core | Stable core surface (preferred for new code) | | brass-runtime/http | Default HTTP client factory, lifecycle middleware, compression, batching, prewarm, adaptive limiter | | brass-runtime/http/testing | Dependency-free mock clients, mock fetch, response factories, and effect runner helpers | | brass-runtime/schema | Dependency-free runtime schema DSL with type inference | | brass-runtime/observability | Prometheus/OTLP exporters, logs, spans, trace propagation, request adapters | | brass-runtime/perf | Runtime, HTTP, observability, memory, and baseline performance profiler | | brass-runtime/agent | Brass Agent core (experimental) |

CLI: brass-agent


HTTP middleware pipeline

The lifecycle client composes middleware in this order (innermost to outermost):

Wire → Priority → Retry → Cache → Batch → Dedup

Adaptive limiting lives in the wire client, before lifecycle middleware. makeDefaultHttpClient can then wrap the lifecycle stack with response compression and caller middleware; caller middleware is outermost.

Each layer is independently optional. Set to false or omit to disable.

| Layer | What it does | |-------|-------------| | Adaptive Limiter | Gradient-based dynamic concurrency control per origin | | Priority | Priority queue for request scheduling (0-9 levels) | | Retry | Exponential backoff with circuit breaker awareness | | Cache | LRU + TTL + stale-while-revalidate | | Batch | Time-window request coalescing with split/distribute | | Dedup | Ref-counted in-flight request deduplication | | Compression | Transparent gzip/br/deflate decompression | | Prewarm | Proactive TCP+TLS connection establishment |

All layers emit lifecycle events, track stats, and support cancellation.

The recommended makeDefaultHttpClient factory wires the default preset for you and accepts extra middleware, so observability can be attached with middleware: [withHttpObservability(obs)] without coupling HTTP to exporters. Per-request policy travels through that stack and is visible to observability without being forwarded to the host transport.


WASM engine

Optional Rust/WASM-backed components for strict execution:

  • Fiber engine state machine
  • Scheduler queue
  • Bounded queues
  • Permit pool
  • Retry planner
npm run build:wasm  # requires wasm-pack

The WASM engine never silently falls back to TypeScript — if you request WASM and it's unavailable, it fails explicitly.


Brass Agent (experimental)

A CLI-first coding agent built on the runtime. Inspects workspaces, discovers validation commands, gathers bounded context, asks an LLM for patches, and applies/rolls back changes under policy.

npm run agent:vscode:install   # VS Code extension
brass-agent --doctor           # check setup
brass-agent --init             # initialize workspace
brass-agent --preset inspect   # run inspection

Docs: Install · CLI · Project intelligence · VS Code


Testing

npm test              # vitest suite
npm run test:types    # TypeScript type checking
npm run test:coverage # coverage with baseline gate
npm run release:check # full release gate: types, tests, build, CJS, perf budgets
npm run benchmark     # runtime, HTTP lifecycle, and 100k local HTTP concurrency
npm run benchmark:runtime        # Runtime Performance Track
npm run benchmark:runtime:budget # Runtime Performance Track regression budget
npm run perf:runtime:ab          # Runtime A/B Performance Lab
npm run perf:runtime:soak        # Runtime-only soak profile
npm run perf:runtime:budget      # Runtime profiler budget
npm run perf:http:memory         # HTTP long-run memory lab
npm run benchmark -- http-concurrent # HTTP compare mode variants
node --expose-gc --import tsx src/benchmarks/runner.ts http-concurrent # HTTP memory/limiter diagnostics
npm run benchmark:adaptive
npm run benchmark:adaptive:soak
npm run benchmark:http:budget
npm run benchmark:http:soak
npm run benchmark:observability
npm run benchmark:observability:budget
npm run smoke:observability:collector # requires local OTEL collector

Property-based tests use fast-check with 100+ iterations per property. Each HTTP middleware has dedicated property tests verifying correctness invariants.


Docs


Features

Runtime (core)

  • [x] Sync effect values via ZIO<R, E, A> aliases
  • [x] Algebraic async: Async<R, E, A>
  • [x] Rich Cause<E> failure trees with pretty printing
  • [x] Interruptibility regions with uninterruptible / uninterruptibleMask
  • [x] Fiber-local refs with fork inheritance and scoped restoration
  • [x] TS TestRuntime with deterministic scheduler and virtual clock
  • [x] Schedule 2.0 with drivers, runtime-clock budgets, observability, and HTTP integration
  • [x] Cooperative scheduler (observable, testable)
  • [x] Fibers with interruption & finalizers
  • [x] Structured scopes & resource safety
  • [x] Runtime flight recorder for bounded execution traces
  • [x] Layer 2.0 typed contexts, semaphores, circuit breakers
  • [x] Metrics, tracing, runtime hooks
  • [x] Worker pools
  • [x] WASM engine (optional)

Streams

  • [x] Pull-based streams with backpressure
  • [x] Fluent Stream / Pipeline DX facade
  • [x] Bounded buffers, queues, hubs
  • [x] Pipelines with fusion optimization
  • [x] Stream merge, zip, broadcast
  • [x] Chunks & batch operators

HTTP

  • [x] Lazy, cancelable HTTP client
  • [x] Effect-based Node HTTP server listener with resource lifecycle
  • [x] Declarative typed routing with params/query/body/response schemas
  • [x] Health/readiness routes backed by runtime health reports
  • [x] Schema-validated JSON helpers
  • [x] Discoverable builder API
  • [x] Test helper subpath
  • [x] Lifecycle client with middleware composition
  • [x] Response cache (LRU + TTL + SWR)
  • [x] Request deduplication (ref-counted)
  • [x] Priority scheduling
  • [x] Retry with exponential backoff
  • [x] Response compression (gzip, br, deflate)
  • [x] Request batching (time-window coalesce/split)
  • [x] Connection pre-warming (probes, auto-refresh)
  • [x] Adaptive concurrency (gradient-based)
  • [x] Adaptive limiter presets, diagnostics, observability gauges, and soak benchmark
  • [x] Circuit breaker
  • [x] Tracing & validation

Schema

  • [x] Dependency-free schema DSL
  • [x] Type inference via InferSchema
  • [x] Object, array, record, union, enum, literal, custom schemas
  • [x] Optional, nullable, refine, transform
  • [x] Path-rich validation issues

Observability

  • [x] Runtime metrics sink and Prometheus exporter
  • [x] OTLP JSON/HTTP exporters for metrics, traces, and logs
  • [x] Structured logging with context propagation and redaction
  • [x] W3C trace-context extract/inject helpers
  • [x] Client and server HTTP observability helpers
  • [x] Adaptive limiter metrics on HTTP client spans and Prometheus gauges
  • [x] Sampling, force-sample-on-error, and bounded trace retention
  • [x] Bounded exporter queues with retry, timeout, drop policy, and single-flight flush
  • [x] Fetch/Node/Express/Fastify/Nest-style examples and collector smoke script

Design notes

  • No hidden Promises — async is always modeled explicitly via Async
  • Deterministic execution — scheduler is observable and testable
  • Resource safety is structural — scopes guarantee cleanup
  • Middleware composes via functions(next: HttpClientFn) => HttpClientFn
  • Cancellation propagates — ref-counted through the entire middleware stack
  • Stats are frozen snapshots — no mutable state leaks to consumers

Contributing

  • Runtime invariants matter — avoid sneaking Promises into core semantics
  • Prefer libraries on top of the runtime over changes in core
  • Add property tests when an invariant is broad
  • Keep tests close to the changed module
  • Small, focused PRs are welcome

License

MIT © 2025