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

@hyperttp/transport-bun

v0.2.4

Published

High-performance HTTP transport for Bun with native fetch optimizations

Readme

BunTransport

BunTransport is a high-performance HTTP transport for the HyperTransport ecosystem, designed for the Bun runtime.

It wraps native fetch and adds:

  • concurrency limiting with FIFO queue
  • request timeouts via AbortSignal
  • automatic cookie handling with TTL and LRU eviction
  • response caching for GET/HEAD requests
  • stealth / fingerprint mimicry (JA3/JA4)
  • header normalization
  • keepalive support
  • TLS configuration (ciphers, rejectUnauthorized)

Interface

export interface HyperTransport {
  execute(req: TransportRequest): Promise<TransportResponse>;
  close?(): Promise<void>;
  destroy?(): Promise<void>;
}

BunTransport implements this interface and can be used as a runtime-specific HTTP transport in client libraries.


Features

  • fetch-based implementation with signal support
  • automatic merging of cookies from responses and subsequent requests
  • cookie cache per domain with configurable TTL
  • response cache for GET/HEAD requests (optional, via hcacher)
  • request concurrency limiting with FIFO queue
  • request timeout support
  • stealth mode: browser-like TLS fingerprint emulation (Chrome, Firefox, Safari, Edge)
  • baseUrl support for relative URLs
  • compatibility with TransportRequest / TransportResponse

Benchmark

Benchmark results on Bun 1.3.14 (20K requests, 200 concurrent, 60s duration):

Environment: linux 7.1.3-zen2-1-zen | Intel Core i5-8600K @ 3.60GHz

| Rank | Client | RPS | Avg | p50 | p90 | p99 | Errors | | ---- | -------------- | ------ | -------- | -------- | -------- | -------- | ------ | | 1 | bun-fetch | 25.92K | 7.65 ms | 7.69 ms | 10.41 ms | 14.00 ms | 0 | | 2 | undici | 21.47K | 9.28 ms | 9.54 ms | 12.80 ms | 14.77 ms | 0 | | 3 | @hyperttp/core | 14.70K | 13.53 ms | 12.03 ms | 17.36 ms | 19.72 ms | 0 | | 4 | axios | 6.24K | 31.85 ms | 31.83 ms | 33.82 ms | 36.10 ms | 0 |

BunTransport (via @hyperttp/core) delivers 2.4x higher throughput than axios with 2.3x lower latency (p50).


Installation

BunTransport is designed for Bun, so the project must run in the Bun runtime.

bun add @hyperttp/transport-bun

Peer dependencies: @hyperttp/types, hcacher.


Usage

import { BunTransport } from "@hyperttp/transport-bun";

const transport = new BunTransport({
  baseUrl: "https://api.example.com",
  network: {
    timeout: 10_000,
    maxConcurrent: 32,
    keepAliveTimeout: 30_000,
    rejectUnauthorized: true,
  },
});

const response = await transport.execute({
  url: "/users",
  method: "GET",
  headers: {},
  body: null,
});

console.log(response.status);
console.log(await response.text());

Configuration

BunTransport accepts a BunTransportConfig object:

interface BunTransportConfig extends HttpClientOptions {
  baseUrl?: string;
  stealth?: StealthOptions;
}

Network options

network?: {
  maxConcurrent?: number;
  timeout?: number;
  keepAliveTimeout?: number;
  rejectUnauthorized?: boolean;
  cookieCache?: {
    enabled?: boolean;
    maxSize?: number;
    ttl?: number;
  };
  cache?: {
    enabled?: boolean;
    maxSize?: number;
    ttl?: number;
  };
}

| Option | Description | | -------------------- | ---------------------------------------------------------------------------------------------- | | maxConcurrent | Maximum number of concurrent active requests (0 = unlimited) | | timeout | Global request timeout in milliseconds (0 = no timeout) | | keepAliveTimeout | Enables keepalive mode when provided | | rejectUnauthorized | Passed to Bun fetch via tls configuration | | cookieCache | Cookie cache settings: enabled (default true), maxSize (default 256), ttl (default 300s) | | cache | Response cache settings for GET/HEAD: enabled, maxSize (default 256), ttl (default 30s) |


Cookies

The transport supports persistent cookie storage with TTL and LRU eviction, backed by hcacher.

How it works

  1. When the server returns Set-Cookie, cookies are stored per domain with a TTL.
  2. On subsequent requests to the same domain, cookies are automatically attached to the Cookie header.
  3. If the user provides their own Cookie header, it is merged with stored cookies.
  4. Expired entries are evicted automatically (LRU).

Example

await transport.execute({
  url: "/login",
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ login: "demo", password: "secret" }),
});

// Cookies from /login are automatically sent
const res = await transport.execute({
  url: "/profile",
  method: "GET",
  headers: {},
  body: null,
});

Response caching

When network.cache is configured, GET and HEAD requests are cached automatically with TTL and LRU eviction.

const transport = new BunTransport({
  network: {
    cache: {
      enabled: true,
      maxSize: 512,
      ttl: 60_000, // 1 minute
    },
  },
});

Cached responses are returned instantly on repeated requests to the same URL within the TTL window.


Concurrency limiting

If maxConcurrent > 0, incoming requests are queued until a slot becomes available.

This is useful for:

  • preventing server overload
  • limiting runtime resource usage
  • avoiding traffic spikes

Timeout & cancellation

The transport uses AbortSignal:

  • if req.signal is provided, it is respected
  • if timeout is set, AbortSignal.timeout(...) is created
  • if both exist, they are combined using AbortSignal.any(...)

If a request is aborted, the signal reason (or a default AbortError) is thrown.


Stealth / fingerprint mimicry

BunTransport supports browser-like TLS fingerprint emulation to bypass fingerprint-based protections (JA3/JA4).

Supported profiles

| Profile | TLS ciphers | sec-ch-ua | User-Agent | | ------- | ------------- | ------------- | ----------- | | chrome | Chrome suite | Chrome 126 | Chrome 126 | | firefox | Firefox suite | Firefox-style | Firefox 126 | | safari | Safari suite | — | Safari 17.0 | | edge | Chrome suite | Chrome 126 | Edge 126 |

Example

const transport = new BunTransport({
  stealth: {
    fingerprint: "chrome",
  },
});

Stealth presets are applied per-request. Manual headers always take priority over preset values.


Response API

execute() returns a plain TransportResponse object:

interface TransportResponse {
  status: number;
  url: string;
  headers: Record<string, string | string[]>;
  body: TransportResponsePayload | null;
}

Body behavior

If body exists, a dump() method may be attached to it, allowing safe stream consumption and resource cleanup.


Internal utilities

fastGetHostname(url: string): string

Fast hostname extraction from a URL with single-entry LRU cache. Handles //, scheme://, user@host, and port stripping.

resolveUrl(baseUrl: string, url: string): string

Resolves a relative URL against a baseUrl. Absolute URLs are returned as-is.

normalizeHeaders(headers): Record<string, string>

Normalizes headers: lowercases all keys, joins arrays (; for cookie, , for others).


Shutdown

BunTransport supports resource cleanup:

await transport.close();
await transport.destroy();

Both methods clear:

  • pending request queue
  • cookie store
  • cookie string cache
  • response cache
  • active request counter

Notes

  • Designed specifically for the Bun runtime, not Node.js.
  • Uses redirect: "manual" for fetch requests.
  • Minimal interference with request data; only headers, cookies, and signals are normalized or extended.
  • TransportRequest.body is passed directly as BodyInit | null.

License

MIT