How to preview a Next.js app an AI agent built
Run next dev in the agent's sandbox with spawn, allow *.runtimehost.com in allowedDevOrigins, and share port 3000 as a preview.
On Runtime each agent's app gets its own microVM and a private HTTPS address in one call. The app never runs on your servers, the address needs a token unless you make it public, and hot reload works because previews carry WebSockets. The sandbox has Node.js 24.21.0; Next.js 16.3.6, current on 25 September 2026, needs 20.9 or later.
Run the agent's app
Upload what the agent wrote, or scaffold a fresh project, then start the dev server and share it:
TypeScriptimport { Sandbox } from "withruntime";const nextConfig = `import type { NextConfig } from "next";const nextConfig: NextConfig = { allowedDevOrigins: ["*.runtimehost.com"] };export default nextConfig;`;const sbx = await Sandbox.create({ timeoutSeconds: 3600 }); // keeps running after this script endsawait sbx.exec("npx create-next-app@16.3.6 site --yes --use-npm --disable-git", { check: true, timeoutMs: 600_000, env: { NEXT_TELEMETRY_DISABLED: "1" },});await sbx.files.write("/workspace/site/next.config.ts", nextConfig);await sbx.spawn("npx next dev -p 3000", { cwd: "/workspace/site", env: { NEXT_TELEMETRY_DISABLED: "1" },});await sbx.exec("npx wait-on@9.1.0 http://127.0.0.1:3000", { check: true, timeoutMs: 180_000 });const preview = await sbx.previews.create(3000);console.log(preview.urlWithToken); // a one-time link for your browserPythonfrom withruntime import SandboxNEXT_CONFIG = """import type { NextConfig } from "next";const nextConfig: NextConfig = { allowedDevOrigins: ["*.runtimehost.com"] };export default nextConfig;"""sbx = Sandbox.create(timeout_seconds=3600)sbx.exec("npx create-next-app@16.3.6 site --yes --use-npm --disable-git", check=True, timeout_ms=600_000, env={"NEXT_TELEMETRY_DISABLED": "1"})sbx.files.write("/workspace/site/next.config.ts", NEXT_CONFIG)sbx.spawn("npx next dev -p 3000", cwd="/workspace/site", env={"NEXT_TELEMETRY_DISABLED": "1"})sbx.exec("npx wait-on@9.1.0 http://127.0.0.1:3000", check=True, timeout_ms=180_000)print(sbx.previews.create(3000)["urlWithToken"])For a project the agent already wrote, replace the scaffold with
sbx.files.upload("./site", "/workspace/site") and npm ci. Upload the source
without its node_modules: packages installed on a Mac carry native binaries
for the wrong system.
Why allowedDevOrigins matters
In development, Next.js blocks requests for dev-only assets and endpoints that
come from an origin other than localhost, its subdomains or the hostname the
server started with. A preview's hostname is a name under runtimehost.com,
so without an entry the page loads but the dev assets it asks for are refused
with 403, and the dev server logs "Blocked cross-origin request to Next.js dev
resource". Hot reload then never connects.
| Setting | Effect |
|---|---|
| No entry | Next.js blocks the preview's requests for dev assets |
allowedDevOrigins: ["*.runtimehost.com"] |
Every preview address works; * covers one label, which is all a preview uses |
next start (production) |
No dev endpoints, so the setting does not apply |
Next.js matches only the hostname of the request's Origin, so write the
entry without https:// and without a port.
Dev server or production build
| Question | next dev |
next build then next start |
|---|---|---|
| Does an edit show at once? | Yes, over hot reload | No; rebuild first |
| Does it match what users would get? | Close, but compiled on request | Yes |
| Who should open it? | The person watching the agent work | A reviewer, a client, a demo |
| Preview visibility | Private, with the one-time link | Public, or private for a reviewer |
To share the finished app:
TypeScriptimport { Sandbox } from "withruntime";const sbx = await Sandbox.connect(process.env.SANDBOX_ID ?? "");const build = await sbx.exec("cd site && npx next build", { timeoutMs: 900_000, onStdout: (text) => process.stdout.write(text),});if (build.exitCode !== 0) throw new Error(build.stdout + build.stderr);await sbx.spawn("npx next start -p 3001", { cwd: "/workspace/site" });await sbx.exec("npx wait-on@9.1.0 http://127.0.0.1:3001", { check: true, timeoutMs: 120_000 });const demo = await sbx.previews.create(3001, { visibility: "public" });console.log(demo.url);A failed build is useful to the agent too: next build checks types, so send
its output back as the next message and the agent sees each error with its file
and line.
How much disk a Next.js app takes
A fresh create-next-app@16.3.6 project, measured on a Linux x86-64 machine on
25 September 2026:
| Part | Size |
|---|---|
node_modules |
476 MB |
.next after next build |
39 MB |
npm's download cache, ~/.npm |
769 MB |
That fits the default 4 GiB disk, which has about 2.5 GiB free, with room to
spare. An agent that adds many packages, or a monorepo, needs more: ask for
diskMiB: 8192 when you create the sandbox. The trial allows up to 10 GiB.
Start from an image with the dependencies installed
Build the project's dependencies into a custom image with a Dockerfile. The lockfile comes first, so a rebuild after a code change reuses the installed packages:
dockerfileFROM runtimeENV NEXT_TELEMETRY_DISABLED=1WORKDIR /workspace/siteCOPY package.json package-lock.json ./RUN npm ci --no-fund --no-auditCOPY . .RUN chown -R 1000:1000 /workspace/sitePythonfrom withruntime import Runtimeruntime = Runtime()with open("site/Dockerfile") as handle: runtime.images.build(name="site", dockerfile=handle.read(), context_dir="site", on_log=lambda line: print(line["text"]))sbx = runtime.sandboxes.create(image="site")sbx.spawn("npx next dev -p 3000", cwd="/workspace/site")print(sbx.previews.create(3000)["urlWithToken"])Keep node_modules and .next in .dockerignore, so the build context holds
only the source.
Related
- Preview apps an AI agent builds
- Preview a Vite dev server
- Test the app with Playwright
- Per-user dev environments
- Custom domains for a finished app
Sources
Checked 25 September 2026.
- allowedDevOrigins:
what Next.js blocks in development, the
localhostdefault, wildcard rules and hostname-only matching - create-next-app:
--yes,--use-npm,--disable-git - next CLI:
-p, default port 3000, Turbopack by default - Next.js installation: Node.js 20.9 or later
- Next.js telemetry:
NEXT_TELEMETRY_DISABLED=1 - next on npm: version 16.3.6
Facts on this page were checked on 25 September 2026.