Adapters
Elysia, Hono, Express, Next.js, TanStack Start, tRPC, and oRPC adapters — thin wiring over one shared core contract.
Every adapter does the same job: open an exchange for the request, apply what it says, report back. The core owns everything else — change registry, pipeline compilation, version resolution, sunsets, telemetry — which is why each adapter is a couple hundred lines of framework-specific glue.
The shared contract
Per request, in order:
- Resolve — the adapter hands core the method, path, matched route (when the framework exposes one), and a header getter; core resolves the effective version and compiles (or cache-hits) the transform pipeline.
- Gate — sunset headers go on the response; a version past its cutoff is
answered
410 Goneright here, and a rewrite target re-dispatches. up(body)— the request body is converted to the current shape before validation and the handler.- Handler — your code runs against the current shape only.
down(body)— the response is converted back to the pinned client's shape (downErrorfor status ≥ 400).finish()— exactly one telemetry event is emitted, off the request path.
Shared behavior across all HTTP adapters:
- JSON only, ≤ 1MB. Only
application/jsonbodies under 1MB are transformed; multipart, binary, form-data, streams, andstream: "passthrough"routes pass through untouched. - Identity is free. When no changes touch the route, or the client is at
current, the pipeline is empty and all body work is skipped. - Sunsets are automatic. Scheduled versions get
Deprecation+Sunsetheaders on every response; past the cutoff the adapter answers410 Goneitself. See Rewrites & sunsets. - Invalid pins fail fast. A malformed version string returns
400 { "error": "invalid_api_version" }before any handler runs. - Telemetry is opt-in. One event per request when a sink is attached;
without an
apiKeyor a manually attached sink, versionless makes zero network calls. A sink error can never fail a request.
Pick your framework
Elysia
Global plugin; up-transforms run before schema validation, downs after.
Hono
One middleware; reads the matched route, swaps request and response bodies.
Express
Classic middleware; ordering matters — express.json() first.
Next.js
Wraps App Router route handlers per file; alias route files for rewrites.
TanStack Start
Wraps server route handlers per file; alias route files for rewrites.
tRPC
Procedure-keyed changes; context + middleware + formatter + responseMeta.
oRPC
Procedure-keyed changes; context + client interceptor + adapter interceptor.
Route matching
Adapters pass the framework's own matched route pattern when they can (Elysia
ctx.route, Hono matchedRoutes, the route option of the Next.js and
TanStack Start wrappers), so core's matcher never runs. Express middleware
can't see the matched route, so core falls back to matching the raw path
against the (small) set of routes that actually have changes. tRPC and oRPC
skip paths entirely — changes are keyed by procedure (trpc:demo.userList).
Serverless
On Vercel (process.env.VERCEL), the batched telemetry sink runs in immediate
mode and every adapter calls exchange.flush() after the response, so events
survive the function freezing.