Skip to main content
Concepts

Deploy

Deploy a directory or generated files with deployApp() and repair failed builds.

deployApp() publishes an app’s files as a new release.

Getting started

Deploy a local application directory:

await deployApp({
  appId: "hello-world",
  source: new URL("./app/", import.meta.url),
});

Or pass a complete generated application tree:

await deployApp({
  appId: "generated-app",
  files: {
    "package.json": JSON.stringify({
      private: true,
      type: "module",
      main: "index.js",
    }),
    "index.js": `
      export default {
        fetch() {
          return new Response("hello");
        },
      };
    `,
  },
});

Bundle requirements

An app needs two things:

  • A package.json.
  • An entrypoint that default-exports a fetch handler.

Dynamic Apps owns the HTTP listener. Application code must not call serve(), listen(), or registry.start().

With Hono, export the app directly:

import { Hono } from "hono";

const app = new Hono();
app.get("/", (c) => c.json({ ok: true }));

export default app;

Build and repair loop

deployApp() rejects with bounded build diagnostics when generated source does not compile. Feed those diagnostics back to the generator and try again:

for (let attempt = 0; attempt < 3; attempt++) {
  try {
    await deployApp({ appId: "generated-app", files });
    break;
  } catch (error) {
    if (attempt === 2) throw error;
    files = await repairWithAgent(files, String(error));
  }
}

A failed build never replaces the active release. A successful call resolves only after the new release is persisted and activated. Activation is all-or-nothing and rolls out instantly: warm VMs load the new release on the next request.

Configuration

OptionDefaultMeaning
createNamespacetrueSet false to disable namespace provisioning entirely. Unset keeps the default. Apps that use rivetkit require a namespace

See Connect to Rivet for credentials and namespace setup.