Skip to main content
Blog

Introducing Dynamic Apps: Deploy AI-Generated Apps for Your Users

Dynamic Apps is the library for deploying the apps your users generate. Powered by V8 isolates, it scales to zero, runs in your backend, and ships with batteries-included serverless infrastructure.

Introducing Dynamic Apps: Deploy AI-Generated Apps for Your Users

Today we’re launching Dynamic Apps, a library for deploying AI-generated apps for every one of your users. It runs as a library inside your backend and is an open-source alternative to Cloudflare Workers for Platforms, Cloudflare Dynamic Workers, and Cloudflare Durable Object Facets.

By leveraging lightweight V8 isolates, we’re able to give each user their own app for incredibly cheap. An app takes 32 MB of memory while serving and scales to zero when idle, with no cold starts. This lets you scale to millions of deployments affordably.

It runs as a library in your backend, so you can deploy to any cloud, in your VPC, on-prem, or locally on your laptop.

npm add @rivet-dev/dynamic-apps

Generate, deploy, route

We’ve made it incredibly simple to generate code with AI and deploy it for your users.

1. Generate. An LLM writes the app as a set of files. Any model, any framework.

import { anthropic } from "@ai-sdk/anthropic";
import { generateText, Output } from "ai";
import { z } from "zod";

const { output } = await generateText({
  model: anthropic("claude-sonnet-4-5"),
  output: Output.object({
    schema: z.object({ files: z.record(z.string(), z.string()) }),
  }),
  prompt: "Build a team board as a complete web app.",
});

2. Deploy. One call builds the files and publishes a release to the user’s app pied-piper.

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

await deployApp({
  appId: "pied-piper",
  files: output.files,
});

3. Route. Your Hono server serves every deployed app at /apps/:appId.

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

const server = new Hono();
server.route("/apps", appsRouter);

serve({ fetch: server.fetch, port: 3000 });

Built as a library, not a SaaS

Requests reach your router first, so your routing, middleware, and auth apply before the app ever sees them.

Traditional SaaSYOUR NODE.JS PROCESSRequestYour codeExternal APItheir infrastructureDynamic AppsYOUR NODE.JS PROCESSRequestYour codeDynamic Appsa library, user apps run here

Each user’s app runs in its own V8 isolate and scales to zero when idle. All of this runs inside your own backend with a tiny memory footprint, so your deployment model stays simple, you keep full control over how requests reach each user’s app, and there’s no per-app or per-request bill from a third party: you pay only for the compute you already run.

Comes with the infrastructure real apps need

Serving frontends and REST APIs alone isn’t very useful without persistence or infrastructure behind them. One of the challenges of AI-generated applications is finding infrastructure that stays affordable across millions of instances, one for every generated app, and can scale instantly when a user’s app gets load.

Dynamic Apps integrates with Rivet Actors and Rivet Workflows.

Every app gets, out of the box:

  • REST APIs & frontends
  • SQLite
  • Workflows & queues
  • Crons & schedules
  • Realtime multiplayer
  • Static sites

Agents also get the Rivet cookbooks as skills, so they have architecture recommendations for production-ready applications while they generate.

For example, here’s a generated app that processes an order as a durable workflow:

// Example workflow generated by an LLM
import { actor, setup } from "rivetkit";
import { workflow } from "@rivet-dev/workflows";

const order = actor({
  state: { status: "placed" as "placed" | "paid" | "shipped" | "delivered" },
  actions: {
    status: (c) => c.state.status,
  },
  run: workflow(async (wf) => {
    await wf.step("charge", async (c) => {
      await chargeCard(c.key[0]);
      c.state.status = "paid";
    });
    await wf.step("ship", async (c) => {
      await createShipment(c.key[0]);
      c.state.status = "shipped";
    });
    // Survives restarts; the app scales to zero while it sleeps
    await wf.sleep("in transit", 3 * 24 * 60 * 60 * 1000);
    await wf.step("deliver", async (c) => {
      c.state.status = "delivered";
    });
  }),
});

export const registry = setup({ use: { order } });
registry.start();

Deploy it like any other app, then talk to the workflow from your backend with the RivetKit client.

import { deployApp } from "@rivet-dev/dynamic-apps";
import { createClient } from "rivetkit/client";
import type { registry } from "./app";

// Build and release the generated files as an isolated app
const deployment = await deployApp({ appId: "pied-piper", files });

// Connect to the actors inside that app's own Rivet namespace
const client = createClient<typeof registry>({
  namespace: deployment.namespace,
  poolName: deployment.pool,
});

// Start (or look up) the order workflow and read its status
const order = client.order.getOrCreate(["order-1042"]);
console.log(await order.status()); // "paid"

Each app runs in its own isolated Rivet namespace: it costs nothing when idle, scales to millions instantly, gives you complete per-tenant isolation, and makes per-customer billing trivial.

Security

Dynamic Apps is built on agentOS, which uses V8 isolates and WebAssembly to provide a secure Linux-like environment for executing code. It’s what makes it possible to run Node.js securely at native V8 speeds.

This security model mirrors the one you’ll find inside Chromium and Cloudflare Workers. We’ve documented it in the agentOS security model.

agentOS also provides granular limits on what user-deployed applications can do, including network, resources, and more. See the resource limits docs for details.

Everything you expect, out of the box

Everything you need to build user-generated applications comes included:

  • Automatic type checking of AI-generated code for repair loops
  • Automatic log collection
  • Resource limits
  • Install any npm package
  • Node.js and Python support
  • Network restrictions per app
  • Global edge network
  • Scale to zero