Deploying Apps
Deploy a directory or generated files with deployApp(), preserve rollback, and configure app actors.
Deploy a local application directory:
await deployApp({
appId: "hello-world",
source: new URL("../fixtures/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");
},
};
`,
},
});
The direct entrypoint must default-export a function or an object with
fetch(request). Code runs inside agentOS with filesystem, process,
environment, and network permissions, and supported Node builtins are
available. Directories that contain only static files are rejected; see
Static Websites. Native addons are not
supported.
Build repair and rollback
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));
}
}
Include webServerSkill and rivetActorsSkill from @rivet-dev/dynamic-apps
in the model prompt. They describe the supported TypeScript server layout and
Rivet actor integration. View the complete AI App Builder example.
A failed build or incomplete artifact write never replaces the active release. A successful call returns only after the immutable artifact is persisted and activated; it does not mean a request-serving replica was warmed.
With core, this is the publishRelease guarantee: make the complete artifact
durable first, atomically replace the active release second, and resolve only
when loadActiveRelease can read it. The default adapter provides those
semantics through its per-app Rivet actor.
appId must contain 1–63 lowercase letters, numbers, or hyphens. Pass exactly
one of source or files.
Configuration
await deployApp({
appId: "my-app",
source,
regions: ["atl", "fra"],
scaling: {
minReplicas: 0,
maxReplicas: 128,
targetConcurrency: 8,
},
});
| Option | Default | Meaning |
|---|---|---|
regions | State actor’s current region | Stored compatibility metadata; it does not move direct HTTP execution |
createNamespace | none | Deprecated compatibility option; every app always receives its own stable namespace |
scaling.minReplicas | 0 | App-defined actor runner setting; compatibility metadata for direct HTTP |
scaling.maxReplicas | 128 | App-defined actor runner setting; compatibility metadata for direct HTTP |
scaling.targetConcurrency | 8 | App-defined actor runner setting; compatibility metadata for direct HTTP |
Every app receives its own Rivet namespace. Locally, configure an Engine secret
token with permission to create namespaces. On Rivet Cloud, set
RIVET_CLOUD_TOKEN to a cloud_api_* token for the project; deployApp() uses
it to create the namespace and namespace-scoped actor credentials. Keep this
management token server-side. The deployment result includes the app’s Engine
endpoint, namespace, pool, and publishable token for connecting to app-defined
actors.
Rivet Compute automatically uses the deployment’s .rivet.run/api/rivet
callback. For another public host, set DYNAMIC_APPS_CALLBACK_URL to its
origin.