
Vercel Sandbox
OfficialFreeRun headless Chrome in isolated Vercel environments.
Free · Opens the source repo
What Vercel Sandbox does
Vercel Sandbox enables developers to run browser automation using headless Chrome within ephemeral microVMs on Vercel. This skill is particularly useful for any Vercel-deployed applications, including those built with frameworks like Next.js, SvelteKit, Nuxt, Remix, and Astro. By leveraging the sandbox environment, users can execute browser commands without the constraints of binary size limits, ensuring efficient automation workflows.
The core functionality revolves around spinning up a Linux VM that executes browser commands on demand. This allows for persistent browser sessions across multiple commands, making it ideal for tasks that require a series of interactions with a web application. The skill supports various automation tasks, such as taking screenshots, filling out forms, and capturing accessibility snapshots, all while maintaining a clean and isolated environment that can be created and destroyed as needed.
To get started, users simply need to install the required dependencies and utilize the provided API to interact with the sandbox. The documentation includes code snippets that demonstrate how to open a URL, take screenshots, and handle multi-step workflows seamlessly. Additionally, the use of sandbox snapshots allows for rapid startup times, significantly improving the efficiency of automation tasks by avoiding the overhead of installing dependencies each time.
This skill is designed for developers who need reliable browser automation capabilities within their Vercel applications. Whether you're testing web applications, scraping data, or running scheduled tasks, Vercel Sandbox provides a robust solution that integrates smoothly with your existing workflows.
When to use it
Use this skill when you need to automate browser tasks in a Vercel app and require persistent sessions or isolated environments.
When not to use it
This skill may not be suitable for applications that do not run on Vercel or for tasks that require direct interaction with a graphical user interface.
What you can build with it
Automated Testing
Run automated tests on your web applications by simulating user interactions and capturing the results.
Data Scraping
Use Vercel Sandbox to scrape data from websites without worrying about binary size limits or environment setup.
Scheduled Reporting
Set up scheduled tasks to run browser commands at specified intervals, such as capturing website snapshots or monitoring changes.
How to install Vercel Sandbox
View source1. Install with the skills CLI
npx skills add vercel-labs/agent-browser/vercel-sandbox --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by vercel-labsBrowser Automation with Vercel Sandbox
Run agent-browser + headless Chrome inside ephemeral Vercel Sandbox microVMs. A Linux VM spins up on demand, executes browser commands, and shuts down. Works with any Vercel-deployed framework (Next.js, SvelteKit, Nuxt, Remix, Astro, etc.).
Dependencies
pnpm add @agent-browser/sandbox @vercel/sandbox
The sandbox VM needs system dependencies for Chromium plus agent-browser itself. The @agent-browser/sandbox helpers install them by default for fresh sandboxes and use sandbox snapshots (below) for sub-second startup. Pass installSystemDependencies: false only when the sandbox image already provides Chromium's required libraries.
Core Pattern
import {
createAgentBrowserSnapshot,
runAgentBrowserCommand,
withAgentBrowserSandbox,
type VercelSandboxSession,
} from "@agent-browser/sandbox/vercel";
async function withBrowser<T>(
fn: (sandbox: VercelSandboxSession) => Promise<T>,
): Promise<T> {
return withAgentBrowserSandbox(fn);
}
Screenshot
The screenshot --json command saves to a file and returns the path. Read the file back as base64:
export async function screenshotUrl(url: string) {
return withBrowser(async (sandbox) => {
await runAgentBrowserCommand(sandbox, ["open", url]);
const titleResult = await runAgentBrowserCommand<{ data?: { title?: string } }>(sandbox, [
"get", "title",
]);
const title = titleResult.json?.data?.title || url;
const ssResult = await runAgentBrowserCommand<{ data?: { path?: string } }>(sandbox, [
"screenshot",
]);
const ssPath = ssResult.json?.data?.path;
if (!ssPath) throw new Error("Screenshot did not return a file path.");
const b64Result = await sandbox.runCommand("base64", ["-w", "0", ssPath]);
const screenshot = (await b64Result.stdout()).trim();
await runAgentBrowserCommand(sandbox, ["close"], { json: false });
return { title, screenshot };
});
}
Accessibility Snapshot
export async function snapshotUrl(url: string) {
return withBrowser(async (sandbox) => {
await runAgentBrowserCommand(sandbox, ["open", url]);
const titleResult = await runAgentBrowserCommand<{ data?: { title?: string } }>(sandbox, [
"get", "title",
]);
const title = titleResult.json?.data?.title || url;
const snapResult = await runAgentBrowserCommand(sandbox, ["snapshot", "-i", "-c"], {
json: false,
});
await runAgentBrowserCommand(sandbox, ["close"], { json: false });
return { title, snapshot: snapResult.stdout };
});
}
Multi-Step Workflows
The sandbox persists between commands, so you can run full automation sequences:
export async function fillAndSubmitForm(url: string, data: Record<string, string>) {
return withBrowser(async (sandbox) => {
await runAgentBrowserCommand(sandbox, ["open", url]);
const snapResult = await runAgentBrowserCommand(sandbox, ["snapshot", "-i"], {
json: false,
});
const snapshot = snapResult.stdout;
// Parse snapshot to find element refs...
for (const [ref, value] of Object.entries(data)) {
await runAgentBrowserCommand(sandbox, ["fill", ref, value]);
}
await runAgentBrowserCommand(sandbox, ["click", "@e5"]);
await runAgentBrowserCommand(sandbox, ["wait", "--load", "networkidle"]);
const ssResult = await runAgentBrowserCommand<{ data?: { path?: string } }>(sandbox, [
"screenshot",
]);
const ssPath = ssResult.json?.data?.path;
if (!ssPath) throw new Error("Screenshot did not return a file path.");
const b64Result = await sandbox.runCommand("base64", ["-w", "0", ssPath]);
const screenshot = (await b64Result.stdout()).trim();
await runAgentBrowserCommand(sandbox, ["close"], { json: false });
return { screenshot };
});
}
Sandbox Snapshots (Fast Startup)
A sandbox snapshot is a saved VM image of a Vercel Sandbox with system dependencies + agent-browser + Chromium already installed. Think of it like a Docker image: instead of installing dependencies from scratch every time, the sandbox boots from the pre-built image.
This is unrelated to agent-browser's accessibility snapshot feature (agent-browser snapshot), which dumps a page's accessibility tree. A sandbox snapshot is a Vercel infrastructure concept for fast VM startup.
Without a sandbox snapshot, each run installs system deps + agent-browser + Chromium (~30s). With one, startup is sub-second.
Creating a sandbox snapshot
The snapshot must include system dependencies (via dnf), agent-browser, and Chromium:
const snapshotId = await createAgentBrowserSnapshot();
Run this once, then set the environment variable:
AGENT_BROWSER_SNAPSHOT_ID=snap_xxxxxxxxxxxx
A helper script is available in the demo app:
npx tsx examples/environments/scripts/create-snapshot.ts
Recommended for any production deployment using the Sandbox pattern.
Authentication
On Vercel deployments, the Sandbox SDK authenticates automatically via OIDC. For local development or explicit control, set:
VERCEL_TOKEN=<personal-access-token>
VERCEL_TEAM_ID=<team-id>
VERCEL_PROJECT_ID=<project-id>
These are spread into Sandbox.create() calls. When absent, the SDK falls back to VERCEL_OIDC_TOKEN (automatic on Vercel).
Scheduled Workflows (Cron)
Combine with Vercel Cron Jobs for recurring browser tasks:
// app/api/cron/route.ts (or equivalent in your framework)
export async function GET() {
const result = await withBrowser(async (sandbox) => {
await sandbox.runCommand("agent-browser", ["open", "https://example.com/pricing"]);
const snap = await sandbox.runCommand("agent-browser", ["snapshot", "-i", "-c"]);
await sandbox.runCommand("agent-browser", ["close"]);
return await snap.stdout();
});
// Process results, send alerts, store data...
return Response.json({ ok: true, snapshot: result });
}
// vercel.json
{ "crons": [{ "path": "/api/cron", "schedule": "0 9 * * *" }] }
Environment Variables
| Variable | Required | Description |
|---|---|---|
AGENT_BROWSER_SNAPSHOT_ID | No (but recommended) | Pre-built sandbox snapshot ID for sub-second startup (see above) |
VERCEL_TOKEN | No | Vercel personal access token (for local dev; OIDC is automatic on Vercel) |
VERCEL_TEAM_ID | No | Vercel team ID (for local dev) |
VERCEL_PROJECT_ID | No | Vercel project ID (for local dev) |
Framework Examples
The pattern works identically across frameworks. The only difference is where you put the server-side code:
| Framework | Server code location |
|---|---|
| Next.js | Server actions, API routes, route handlers |
| SvelteKit | +page.server.ts, +server.ts |
| Nuxt | server/api/, server/routes/ |
| Remix | loader, action functions |
| Astro | .astro frontmatter, API routes |
Example
See examples/environments/ in the agent-browser repo for a working app with the Vercel Sandbox pattern, including a sandbox snapshot creation script, streaming progress UI, and rate limiting.
Frequently asked questions about Vercel Sandbox
Similar skills
Spring Boot Testing
Master testing techniques for Spring Boot 4 applications.
GitHub Issues
Manage GitHub issues efficiently with MCP tools.
Geofeed Tuner
Optimize your IP geolocation feeds in CSV format.
Batch Files
Master Windows batch scripting for automation and task management.
Adobe Illustrator Scripting
Automate your Illustrator workflows with ExtendScript.
Plugin Structure
Create and organize Claude Code plugins effectively.
