website/src/content/posts/2025-12-03-ai-generated-backends/page.mdx
Rivet now supports programmatically deploying AI-generated and user-generated actor code to sandboxed namespaces, enabling use cases like AI code execution, user sandbox environments, preview deployments, and multi-tenant applications.
When AI agents generate backend code, they typically need to coordinate across multiple disconnected systems:
Each system requires separate context, increasing token usage and cognitive load for the AI. More importantly, state and behavior can drift apart when defined separately, leading to bugs and inconsistencies.
Rivet Actors solve this by unifying state and logic in a single actor definition. Instead of coordinating between databases and APIs, state and behavior live together:
<Tabs> <Tab title="With Rivet">export const user = actor({
// State is defined alongside behavior
createState: (c, input) => ({
name: input.name,
email: input.email,
createdAt: Date.now(),
}),
// Actions can read and mutate state
actions: {
updateEmail: (c, email: string) => {
c.state.email = email;
},
getProfile: (c) => c.state,
},
});
CREATE TABLE users (
id UUID PRIMARY KEY,
name TEXT NOT NULL,
created_at BIGINT NOT NULL
);
ALTER TABLE users ADD COLUMN email TEXT NOT NULL DEFAULT '';
CREATE INDEX idx_users_email ON users(email);
import { Hono } from "hono";
import { db } from "./db";
const app = new Hono();
app.post("/users/:id", async (c) => {
const { id } = c.req.param();
const { name, email } = await c.req.json();
await db.query(
"INSERT INTO users (id, name, email, created_at) VALUES ($1, $2, $3, $4)",
[id, name, email, Date.now()]
);
return c.json({ success: true });
});
app.patch("/users/:id/email", async (c) => {
const { id } = c.req.param();
const { email } = await c.req.json();
await db.query(
"UPDATE users SET email = $1 WHERE id = $2",
[email, id]
);
return c.json({ success: true });
});
app.get("/users/:id", async (c) => {
const { id } = c.req.param();
const result = await db.query(
"SELECT name, email, created_at FROM users WHERE id = $1",
[id]
);
return c.json(result.rows[0]);
});
This consolidation eliminates fragmentation:
Sandboxed namespaces provide isolated environments where each AI-generated or user-generated deployment runs independently with its own resources, tokens, and configuration. This enables safe multi-tenant deployments and user-generated code execution.
Sandboxed namespaces enable a variety of isolated deployment scenarios:
The deployment process involves four key steps:
Create sandboxed namespace: Programmatically create an isolated Rivet namespace using the Cloud API or self-hosted Rivet API
Generate tokens: Create the necessary authentication tokens:
Deploy code: Deploy the actor code and frontend programmatically to your serverless platform of choice (Vercel, Netlify, AWS Lambda, Freestyle, etc.)
Connect Rivet: Configure Rivet to run actors on your deployment in your sandboxed namespace
Here's a simplified example of the deployment flow using Freestyle (built specifically for this use case):
import { RivetClient } from "@rivetkit/engine-api-full";
import { FreestyleSandboxes } from "freestyle-sandboxes";
async function deploy(projectDir: string) {
// Step 1: Create sandboxed namespace
const { project, organization } = await cloudRequest("GET", "/tokens/api/inspect");
const { namespace } = await cloudRequest(
"POST",
`/projects/${project}/namespaces?org=${organization}`,
{ displayName: `ns-${Date.now()}` }
);
// Step 2: Generate tokens
// ...omitted...
// Step 3: Deploy to Freestyle
const freestyle = new FreestyleSandboxes({ apiKey: FREESTYLE_API_KEY });
const deploymentSource = prepareDirForDeploymentSync(projectDir);
await freestyle.deployWeb(deploymentSource, {
envVars: {
RIVET_ENDPOINT: "https://api.rivet.dev",
RIVET_NAMESPACE: namespace.access.engineNamespaceName,
RIVET_TOKEN: runnerToken,
},
entrypoint: "src/backend/server.ts",
domains: [FREESTYLE_DOMAIN],
});
// Step 4: Configure Rivet to run actors on the deployment
const rivet = new RivetClient({
environment: "https://api.rivet.dev",
token: accessToken,
});
await rivet.runnerConfigsUpsert("default", {
datacenters: {
"us-west-1": {
serverless: {
url: `https://${FREESTYLE_DOMAIN}/api/rivet`,
headers: {},
maxRunners: 1000,
},
},
},
namespace: namespace.access.engineNamespaceName,
});
}
Call this deployment function whenever your AI agent generates new actor code or a user requests their own sandbox environment. The entire process takes seconds and creates a fully isolated, production-ready deployment.
To try deploying AI-generated or user-generated Rivet Actors: