Zen Router

Supported runtimes

How to run Zen Router on Cloudflare Workers, Bun, and other runtimes.

Both ZenRouter and ZenRelay expose a .fetch method that is a standard (request: Request) => Promise<Response> handler. This makes them compatible with any runtime that supports the Web Request/Response API.

Cloudflare Workers

Simple! Just export the router as the default export. Cloudflare Workers calls .fetch automatically.

src/worker.ts
import { ZenRouter } from "@liveblocks/zenrouter";

const zen = new ZenRouter({ ... });

zen.route("GET /api/health", () => ({ status: "ok" }));
zen.route("GET /api/posts/<postId>", async ({ p }) => { ... });
zen.route("POST /api/posts", bodySchema, async ({ body }) => { ... });

// Just use a default export in your worker file
export default zen;

Bun

Simple! Just pass .fetch to Bun.serve():

src/index.ts
import { ZenRouter } from "@liveblocks/zenrouter";

const zen = new ZenRouter({ ... });

zen.route("GET /api/health", () => ({ status: "ok" }));
zen.route("GET /api/posts/<postId>", async ({ p }) => { ... });
zen.route("POST /api/posts", bodySchema, async ({ body }) => { ... });

// Pass zen.fetch to Bun.serve()
Bun.serve({ fetch: zen.fetch, port: 8000 });

Node.js

Node.js uses IncomingMessage/ServerResponse instead of the Web Request/Response API, so you need an adapter. We recommend @whatwg-node/server:

src/index.ts
import { createServer } from "node:http";
import { createServerAdapter } from "@whatwg-node/server";
import { ZenRouter } from "@liveblocks/zenrouter";

const zen = new ZenRouter({ ... });

zen.route("GET /api/health", () => ({ status: "ok" }));
zen.route("GET /api/posts/<postId>", async ({ p }) => { ... });
zen.route("POST /api/posts", bodySchema, async ({ body }) => { ... });

const server = createServer(createServerAdapter(zen.fetch));
server.listen(8000);

On this page

Made withHeartby Liveblocks