CLI tool
h3js/srvx avatar
h3js/srvx

srvx runs one web standard handler on Deno, Bun and Node.js

λ Universal Server based on web standards.

879 stars65 forksTypeScriptMIT

At a glance

What is it?
srvx is a zero dependency TypeScript server that ships a Web Request handler and lets you run it unchanged on Node.js, Deno, Bun, Cloudflare Workers, AWS Lambda and a service worker, with a CLI for local development.
Who is it for?
srvx fits teams that want to write a Request handler once and move it between Deno, Bun, Node.js and edge platforms without a framework, and it suits local development because the CLI ships a watcher, logger and static file serving.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A fetch handler is the only contract srvx asks you to keep

srvx takes the Web platform Request and Response objects as its contract and builds a server around them. The example given in the quick start is a module with a single fetch method that returns a JSON response, and that module is what you point the server at.

js
export default {
  fetch(req: Request) {
    return Response.json({ hello: "world!" });
  },
};

There is no application object, no router and no context type to learn. That is the whole design: the request arrives as a standard Request, the handler returns a standard Response, and the runtime adapter takes care of the rest. The repository is written in TypeScript and the published package declares a zero dependency policy, so the surface area you inherit is the code you write plus the adapter you choose. The package description is a short one, Universal Server, and the project positions itself as a universal server based on web standards, which explains why the same handler can be mounted on a Node.js http server, a Deno serve call, a Bun serve call, or a Cloudflare Workers module.

One package.json exports map decides where your handler runs

The adapter selection is done through conditional exports rather than runtime detection, so the resolution is visible in package.json. The root export lists a deno condition pointing at the Deno adapter, a bun condition pointing at the Bun adapter, a workerd condition pointing at the Cloudflare adapter, a browser condition pointing at the service worker adapter, a node condition pointing at the Node.js adapter, and a default condition pointing at a generic adapter. Subpath exports expose the individual pieces, including cli, static, body-limit, log, tracing, loader, mtls, and dedicated adapters for deno, bun, node, cloudflare, bunny, generic, service-worker and aws-lambda. A Cloudflare Worker and a Node.js process can therefore run the same source file, and the difference sits in which export condition the bundler or runtime satisfies. The examples directory makes the intent concrete, with separate folders for aws-lambda, elysia, express, fastify, h3, hello-world, hono, jsx, node-handler, service-worker, stackblitz, streaming, tracing and websocket.

The CLI runs the handler without a build step on four runtimes

You do not need to write a server bootstrap to see a response. The quick start shows a plain module export, and then the same command shape across four package managers and runtimes.

bash
# Node.js
$ npx srvx       # npm
$ pnpx srvx      # pnpm
$ yarn dlx srvx  # yarn

# Deno
$ deno -A npm:srvx

# Bun
$ bunx --bun srvx

The documentation also lists a fetch subcommand, srvx fetch, which calls the handler directly and prints the result without opening a listening socket, which is useful for checking a response before wiring up the port.

bash
$ npx srvx fetch /api/users

The README describes the CLI as full featured, with a watcher, an error handler, static file serving and a logger. The repository layout backs that up: bin holds the srvx binary, and the build uses obuild through the build script, with the dev script running vitest dev for interactive tests.

Node.js runs through an adapter, and the README claims near native speed

The Node.js path is the interesting one for existing backends, because Node.js does not hand you Request and Response objects for free. srvx keeps a dedicated node adapter and a dedicated deno adapter in the exports map, and the documentation lists Node.js compatibility as a supported scenario with a link to a benchmark folder in the repository under test/bench-node. The repository also carries URL benchmarks wired to three runtimes, with scripts for bun, deno and node, so the project is at least measuring rather than assuming. The claim in the README is close to native performance for the Node.js adapter, and that is a claim by the project rather than a measurement anyone outside the team has confirmed. Practically, this means the compatibility layer sits between a plain Request and Node's http server, and the cost of that translation is the thing to watch if you are moving a hot path over.

Zero overhead on Deno and Bun is the reason the adapters exist

On Deno and Bun there is no translation layer to pay for, because both runtimes already speak the Fetch API. The README lists zero overhead support for those two, and the adapter files exist to pick the right native entry point rather than to emulate anything. The cost of srvx is therefore concentrated on Node.js and on edge platforms where the worker model differs from a long running process. The same split shows up in the server instance API, which the documentation presents as the alternative to the plain handler, giving a server object when you want to configure a port, a hostname or lifecycle hooks instead of exporting a bare module. Both the handler form and the instance form are described as the same API across runtimes, so the choice between them is about how much you want to configure, not about which runtime you are on.

MIT licensing and a fast release cadence keep adoption cheap

The package is published under the MIT licence, and the repository carries the same licence in a LICENSE file, with the package manifest repeating it. MIT is permissive and the manifest marks the package as side effect free, which matters for bundlers that tree shake. The project is versioned at 1.0.6 in the manifest, with v1.0.6 released on 2026-10-17, v1.0.5 on 2026-09-14 and v1.0.4 on 2026-09-07. The last push was on 2026-10-20, so the project is being changed right now rather than sitting still. The dependency list is worth noting for an organisation with a supply chain review process: with zero dependencies, there is no transitive tree to audit, and the repository shows a Renovate configuration for keeping tooling current. The trade-off is that the feature set you get is what the maintainers decided to build, and there is no compatibility policy document in the repository to point at when an upgrade changes behaviour.

What srvx deliberately leaves out of scope

Read the feature list carefully and the absences are as informative as the entries. There is no router, no middleware pipeline, no typed request context, no schema validation and no ORM. The listed capabilities are a handler, a server instance, static serving, a body limit, logging, tracing, mutual TLS and a loader, which is the plumbing of a server rather than an application framework. If you need path parameters, a request scoped user object or automatic validation, you will be reaching for another library, and the examples directory shows exactly that pattern with express, fastify, hono, elysia and h3 folders showing srvx hosted inside other frameworks. The docs at srvx.h3.dev carry the detail that the README leaves out, and the repository includes a docs folder, so the API surface is documented but is spread across the site rather than in the readme.

Editorial conclusion

srvx fits teams that want to write a Request handler once and move it between Deno, Bun, Node.js and edge platforms without a framework, and it suits local development because the CLI ships a watcher, logger and static file serving. It does not suit applications that need a routing library, a middleware stack or a typed request context, since the project documents an API and a CLI rather than a full framework, and it does not suit a Node.js project that already has a working http server. Before adopting it, check the export condition you need in package.json against your deployment target, confirm the adapter for your platform exists in the exports map, and run the CLI locally with the same runtime you plan to deploy to. The last push was on 2026-10-20 and the current version is 1.0.6.

Frequently asked questions

How do I install and run srvx on Node.js?

Export a handler that takes a Request and returns a Response, then start the server with the CLI. The quick start lists npx srvx for npm, with pnpm, yarn, Deno and Bun equivalents, and the CLI documentation lists further options.

Does srvx have any npm dependencies?

The project lists zero dependency as a feature, and the repository is written in TypeScript. The published package only ships the bin and dist directories.

Can I call my srvx handler without starting a server?

Yes. The CLI has a fetch subcommand, shown in the quick start as srvx fetch /api/users, which calls the handler directly and returns the response without opening a listening socket.

Which runtimes and platforms does srvx support?

The README states it works with Deno, Bun and Node.js, and the exports map in package.json adds adapters for Cloudflare, AWS Lambda, Bunny, a service worker and a generic target. The examples directory also shows srvx running alongside express, fastify, hono, elysia and h3.

What is the current version of srvx and how often is it released?

The manifest lists version 1.0.6, and the recent tags are v1.0.6 on 2026-10-17, v1.0.5 on 2026-09-14 and v1.0.4 on 2026-09-07. The last push was on 2026-10-20.

Official sources

  1. h3js/srvx on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/h3js-srvx.svg)](https://hysenlabs.com/projects/h3js-srvx)

Was this useful?