HTTP Server
Different ways to run your RivetKit HTTP server.
Methods of Running Your Server
registry.start()
The simplest way to run your server. Starts a local manager server, serves static files from a public directory, and starts the actor runner:
import { actor, setup } from "rivetkit";
const myActor = actor({ state: {}, actions: {} });
const registry = setup({ use: { myActor } });
registry.start();
Run with npx tsx --watch index.ts (Node.js), bun --watch index.ts (Bun), or deno run --allow-net --allow-read --allow-env --watch index.ts (Deno). The server starts on http://localhost:6420 by default.
With Fetch Handlers
A fetch handler is a function that takes a Request and returns a Response. This is the standard pattern used by Cloudflare Workers, Deno Deploy, Bun, and other modern runtimes.
Use registry.serve() to get a fetch handler:
import { actor, setup } from "rivetkit";
const myActor = actor({ state: {}, actions: {} });
const registry = setup({ use: { myActor } });
export default registry.serve();
To integrate with a router like Hono or Elysia, use registry.handler():
import { Hono } from "hono";
import { actor, setup } from "rivetkit";
const myActor = actor({ state: {}, actions: {} });
const registry = setup({ use: { myActor } });
const app = new Hono();
app.get("/health", (c) => c.text("OK"));
app.all("/api/rivet/*", (c) => registry.handler(c.req.raw));
export default app;
import { Elysia } from "elysia";
import { actor, setup } from "rivetkit";
const myActor = actor({ state: {}, actions: {} });
const registry = setup({ use: { myActor } });
const app = new Elysia()
.get("/health", () => "OK")
.all("/api/rivet/*", ({ request }) => registry.handler(request));
export default app;
Then run your server:
npx tsx --watch server.ts
bun --watch server.ts
deno run --allow-net --allow-read --allow-env --watch server.ts
Explicit HTTP Server
If you need to explicitly start the HTTP server instead of using the fetch handler pattern:
Using Hono with @hono/node-server:
import { Hono } from "hono";
import { serve } from "@hono/node-server";
import { actor, setup } from "rivetkit";
const myActor = actor({ state: {}, actions: {} });
const registry = setup({ use: { myActor } });
const app = new Hono();
app.all("/api/rivet/*", (c) => registry.handler(c.req.raw));
serve({ fetch: app.fetch, port: 3000 });
Using @whatwg-node/server to adapt the fetch handler to Node’s HTTP server:
import { actor, setup } from "rivetkit";
import { createServer } from "node:http";
import { createServerAdapter } from "@whatwg-node/server";
const myActor = actor({ state: {}, actions: {} });
const registry = setup({ use: { myActor } });
const handler = createServerAdapter(registry.serve().fetch);
const server = createServer(handler);
server.listen(3000);
Using Bun’s native server:
import { actor, setup } from "rivetkit";
const myActor = actor({ state: {}, actions: {} });
const registry = setup({ use: { myActor } });
Bun.serve({
port: 3000,
fetch: (request: Request) => registry.handler(request),
});
Using Deno’s native server:
import { actor, setup } from "rivetkit";
const myActor = actor({ state: {}, actions: {} });
const registry = setup({ use: { myActor } });
Deno.serve({ port: 3000 }, (request: Request) => registry.handler(request));