Skip to main content
General

Quickstart

Start the host server, deploy a generated app, and serve it through agentOS.

View the complete Quickstart example on GitHub.

Install

Use Node.js 22 or newer:

npm add @rivet-dev/dynamic-apps @hono/node-server hono
npm add --save-dev tsx
npm pkg set type=module

Start the host server

Mount the private Rivet callback separately from application traffic. The callback keeps the deployment state actor available; ordinary app requests are served by appsRouter through a cached agentOS VM.

import { serve } from "@hono/node-server";
import { appsRouter } from "@rivet-dev/dynamic-apps";
import { Hono } from "hono";

const server = new Hono();

server.all("/api/rivet/*", (c) => appsRouter.fetch(c.req.raw));

// Mount every deployed application at /apps/:appId.
server.route("/apps", appsRouter);

// Serve the host router over HTTP.
serve({
	fetch: server.fetch,
	port: 3000,
});

Run the server normally:

npx tsx src/server.ts

Deploy an app

Pass a complete application tree to deployApp(). This can be called by an agent, an upload endpoint, or another trusted control-plane process.

import { deployApp } from "@rivet-dev/dynamic-apps";

// An agent, upload endpoint, or any other part of the system can call
// deployApp() with the files it generated.
await deployApp({
	appId: "hello-world",
	files: {
		"package.json": JSON.stringify({
			name: "hello-world-app",
			version: "0.0.0",
			private: true,
			type: "module",
			main: "src/index.ts",
			dependencies: {
				hono: "^4.12.9",
			},
		}),
		"src/index.ts": `
import { Hono } from "hono";

const app = new Hono();

// Serve the application's frontend.
app.get("/", (c) => c.html("<h1>Hello from Dynamic Apps</h1>"));

// Serve a REST API request from the same application.
app.get("/api/hello", (c) => c.json({ message: "Hello from Dynamic Apps" }));

export default app;
`,
	},
});
npx tsx src/deploy.ts

Visit the app

Open http://localhost:3000/apps/hello-world/. The bare /apps/hello-world path redirects to its trailing-slash form.

Deploy the host

By default, Rivet stores actor state on the local file system.

To scale Rivet in production, pick how much of it you want to run yourself:

If you are running your own workers, follow the guide for your hosting provider: