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

@setu-ts/runtime

v0.10.0

Published

Runtime services and HTTP adapters for Node.js, Deno, Bun, and Cloudflare Workers

Readme

@setu-ts/runtime

Each adapter supplies IRuntimeServices.reportError: one JSON line to stderr on Node, Bun and Deno, or the platform log channel on Workers. Serialization and write failures never escape. The kernel and errorHandler use it only without a registered logger, for unhandled errors and handled 5xx respectively; handled 4xx stays silent without a logger.

RuntimePlugin and runtime adapters providing IRuntimeServices for Node.js, Deno, Bun, and Cloudflare Workers.

This package implements the runtime-independence seam: every runtime-specific operation the framework needs is abstracted behind IRuntimeServices (defined in @setu-ts/common) and provided here under the CAPABILITIES.RUNTIME token by the RuntimePlugin. No other package ever touches process, Deno, Bun, or node:/deno:/bun: modules directly.

Installation

# npm (pnpm add / yarn add / bun add work the same way)
npm install @setu-ts/runtime

# Deno
deno add npm:@setu-ts/runtime

What's Inside

| Area | Exports | | --------------- | -------------------------------------------------------------------------------------- | | Plugin | RuntimePlugin, RuntimeOptions, HttpAdapterOptions, RequestBodyTooLargeError | | Detection | detectRuntime, GlobalScope | | Deno adapter | createDenoRuntimeServices, DenoHost, DenoFileInfo, DenoDirEntry | | Node adapter | createNodeRuntimeServices, NodeHost, NodeFsInfo | | Bun adapter | createBunRuntimeServices, BunHost, BunFileInfo | | Workers adapter | createCloudflareRuntimeServices, CloudflareRuntimeOptions | | HTTP adapters | DenoHttpAdapter, NodeHttpAdapter, BunHttpAdapter, CloudflareWorkersHttpAdapter |

Usage

Register the plugin in every application — it is mandatory:

import { createApplication } from '@setu-ts/kernel';
import { RuntimePlugin } from '@setu-ts/runtime';

const app = createApplication({
  plugins: [RuntimePlugin()],
});

app.router.get('/info', (ctx) => {
  const runtime = ctx.services.get<IRuntimeServices>(CAPABILITIES.RUNTIME);
  return ctx.response.json({
    platform: runtime.platform(),
    requestId: runtime.uuid(),
  });
});

await app.start({ port: 3000 });

Force a specific platform (useful for testing):

RuntimePlugin({ platform: 'node' });

Options

| Option | Type | Default | Description | | -------------- | ------------------------- | ----------------- | ----------------------------------------------------------------------------- | | platform | RuntimePlatform | detectRuntime() | Force a platform instead of auto-detecting. | | env | Record<string, unknown> | — | Cloudflare Workers env. Only its string entries populate runtime.env. | | adapters | RuntimeAdapterFactories | — | Internal: override runtime adapter factories. | | httpAdapters | HttpAdapterFactories | built-in four | Internal: override HTTP adapter factories. | | maxBodyBytes | number | — (unbounded) | Cap on the request-body read, enforced where the body is consumed. |

Bounding the request body

RuntimePlugin({ maxBodyBytes: 10 * 1024 * 1024 });

Omitted, the read is unbounded — the released behaviour, byte for byte.

This is the layer no request header can switch off. HttpSecurityPlugin({ requestSize: { maxBodySize } }) refuses on a declared Content-Length before anything is read, which is cheaper and reports earlier; a chunked request declares no length, and since the body read became lazy it happens inside the handler, after every middleware has returned. So the middleware bounds declared lengths and this option bounds the read itself. There are two knobs because the request mapping runs before any plugin and there is no channel between them: mapWebRequestToFrameworkRequest receives a Request and nothing else. Set both, and set maxBodyBytes to the same value as maxBodySize or higher.

A body past the cap rejects with RequestBodyTooLargeError, branded with a 413 HTTP status hint, so an application running errorHandler answers 413 Payload Too Large in its configured format rather than a masked 500. With no errorHandler registered the brand has no reader and the kernel's opaque 500 answers instead.

0 refuses every request that carries a body — it does NOT disable the check, which is what 0 means for maxDepth/maxNodes/maxBatchSize elsewhere in this framework. Omitting the option is the one way to say unbounded. A value that is not a non-negative integer throws at RuntimePlugin(...); NaN in particular would make every comparison against the cap false and silently disable the bound, and Number() of an unset environment variable is exactly NaN.

For in-process oversized-upload tests on Node 24 or Node 26 (up to 26.12.0), build the multipart request body from a Blob or use inject() instead of app.fetch(new Request(..., { body: formData })) with a file. Those releases bundle undici 7.20.0–8.11.2, whose FormData request body throws an uncaught ERR_INVALID_STATE when the runtime cancels it after the cap is exceeded; undici 8.12.0 fixes it, and no released Node bundles that yet. Node 22, Bun and Deno are unaffected, as are real-socket uploads and inject(). The runtime still cancels oversized bodies to enforce the read bound.

Reporting a failed WebSocket handshake

HttpAdapterOptions accepts reportError?: (record: Readonly<Record<string, unknown>>) => void (@since 0.10.0). RuntimePlugin supplies one resolved at CALL time: the registered logger's error, else IRuntimeServices.reportError, and a throwing logger never fails the report. The Node adapter calls it at most once per distinct message per handle when a server-side handshake fails — ws is missing or throws — before answering 500; Deno, Workers and Bun ignore the option. Omitted, the refusal is silent as before.

adapters and httpAdapters are marked @internal — they exist so unit tests can run without OS permissions or real runtime globals, not as application configuration.

env matters only on Workers: the edge has no ambient environment, so without it runtime.env is empty and ConfigPlugin reads nothing. Object bindings (KV, R2, D1, …) are filtered out here and published separately by CloudflarePlugin.

Architecture

Cross-runtime operations (UUID, random bytes, SubtleCrypto, now, hrtime, timers) are identical across Node 22+, Deno, and Bun because they rely on web-standard APIs on globalThis (the framework's floor is Node 22; globalThis.crypto alone would have put it at 19). They are implemented once in src/services/cross-runtime.ts.

Divergent operations (platform, version, hostname, env, exit, fs, workers, dns) are implemented per-adapter via dependency injection: each factory accepts a *Host interface describing only what it needs, defaulting to the real runtime global via a single boundary cast. This makes every adapter fully unit-testable on Deno by passing a fake host — no real Node/Bun, no OS permissions.

Scope

This package provides the runtime services abstraction and the HTTP server adapters. Every adapter implements IHttpAdapter and is registered under CAPABILITIES.HTTP_ADAPTER by RuntimePlugin; app.start({ port }) throws when none is registered for the detected platform.

Platform coverage is not uniform, and the gaps are deliberate rather than pending: on Cloudflare Workers fs is undefined (no edge filesystem), workers and dns are omitted, and exit() throws — there is no process to end.

See the repository's PUBLIC_API.md for the full API contract and ARCHITECTURE.md for how this package fits the plugin architecture.

Exports

@setu-ts/runtime

| Export | Kind | | -------------------------------------- | --------- | | adaptWsModule | function | | asUpgradeEmitter | function | | bindCloudflareSocketToSink | function | | bindDenoSocketToSink | function | | bindWsSocketToSink | function | | buildBunHost | function | | buildNodeHost | function | | createBunRuntimeServices | function | | createBunWebSocketHandlers | function | | createCloudflareRuntimeServices | function | | createDefaultCloudflareWebSocketHost | function | | createDenoDnsResolver | function | | createDenoRuntimeServices | function | | createNodeDnsResolver | function | | createNodeRuntimeServices | function | | createNodeWorkerHost | function | | createRuntimeServices | function | | createUpgradeRequest | function | | createWebSocketTransport | function | | createWebWorkerHost | function | | createWsTransport | function | | detectRuntime | function | | isWebSocketUpgradeRequest | function | | loadWsModule | function | | normalizeFrame | function | | rejectRawUpgrade | function | | RuntimePlugin | function | | toReadyState | function | | toTransportError | function | | toWsReadyState | function | | BunHttpAdapter | class | | CloudflareWorkersHttpAdapter | class | | DenoHttpAdapter | class | | NodeHttpAdapter | class | | NodeUpgradeCoordinator | class | | RequestBodyTooLargeError | class | | RpcInterceptorStore | class | | BunFileInfo | interface | | BunHost | interface | | BunModules | interface | | BunServeHost | interface | | BunServer | interface | | BunServerWebSocket | interface | | BunSocketData | interface | | BunWebSocketHandlers | interface | | CloudflareEnv | interface | | CloudflareRuntimeOptions | interface | | CloudflareServerSocket | interface | | CloudflareWebSocketHost | interface | | CloudflareWebSocketPair | interface | | CreateRuntimeServicesOptions | interface | | DenoDirEntry | interface | | DenoDnsHost | interface | | DenoFileInfo | interface | | DenoHost | interface | | DenoServeHost | interface | | DenoServer | interface | | DenoSrvRecord | interface | | DenoWebSocketLike | interface | | DenoWebSocketUpgrade | interface | | GlobalScope | interface | | HttpAdapterFactories | interface | | HttpAdapterOptions | interface | | NodeDnsModule | interface | | NodeFsInfo | interface | | NodeHost | interface | | NodeIncomingMessage | interface | | NodeModules | interface | | NodeServeHost | interface | | NodeServer | interface | | NodeWorkerLike | interface | | NodeWorkerModules | interface | | RawUpgradeSocket | interface | | RuntimeAdapterFactories | interface | | RuntimeOptions | interface | | UpgradeEmitter | interface | | WebSocketLike | interface | | WebWorkerGlobals | interface | | WebWorkerHostOptions | interface | | WebWorkerLike | interface | | WsModuleLike | interface | | WsServerLike | interface | | WsSocketLike | interface |

@setu-ts/runtime/worker

| Export | Kind | | ------------------ | -------- | | defineWorkerTask | function |

Generated from the package barrel by pnpm run docs:exports; pnpm run check:docs fails when it drifts.