sandbox

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

CRITICAL: Always Use Correct
@vercel/sandbox
Documentation

重要提示: 务必使用正确的
@vercel/sandbox
文档

Your knowledge of
@vercel/sandbox
may be outdated. Follow these instructions before starting on any sandbox-related tasks:
你所掌握的
@vercel/sandbox
相关知识可能已过时。 在开始任何与沙箱相关的任务前,请遵循以下说明:

Official Resources

官方资源

Quick Reference

快速参考

Essential imports:
typescript
// Core SDK
import { Sandbox, Snapshot, Command, CommandFinished } from "@vercel/sandbox";
import { APIError, StreamError } from "@vercel/sandbox";

// For advanced network policy with credential brokering
import type { NetworkPolicyRule, NetworkTransformer } from "@vercel/sandbox";

// For timeouts
import ms from "ms"; // e.g., ms("5m"), ms("1h")
Available runtimes:
typescript
type RUNTIMES = "node24" | "node22" | "python3.13";
必要导入:
typescript
// Core SDK
import { Sandbox, Snapshot, Command, CommandFinished } from "@vercel/sandbox";
import { APIError, StreamError } from "@vercel/sandbox";

// For advanced network policy with credential brokering
import type { NetworkPolicyRule, NetworkTransformer } from "@vercel/sandbox";

// For timeouts
import ms from "ms"; // e.g., ms("5m"), ms("1h")
可用运行时:
typescript
type RUNTIMES = "node24" | "node22" | "python3.13";

Creating Sandboxes

创建沙箱

Basic Creation

基础创建

typescript
import { Sandbox } from "@vercel/sandbox";

const sandbox = await Sandbox.create({
  runtime: "node24",
  resources: { vcpus: 4 }, // 2048 MB RAM per vCPU
  ports: [3000], // Expose up to 15 ports
  timeout: ms("10m"), // Default: 5 minutes
  env: { NODE_ENV: "production" }, // Env vars inherited by all commands
});
typescript
import { Sandbox } from "@vercel/sandbox";

const sandbox = await Sandbox.create({
  runtime: "node24",
  resources: { vcpus: 4 }, // 每个vCPU对应2048 MB内存
  ports: [3000], // 最多暴露15个端口
  timeout: ms("10m"), // 默认:5分钟
  env: { NODE_ENV: "production" }, // 所有命令继承的环境变量
});

With Git Source

基于Git源

typescript
const sandbox = await Sandbox.create({
  source: {
    type: "git",
    url: "https://github.com/vercel/sandbox-example-next.git",
    depth: 1, // Shallow clone (optional)
    revision: "main", // Branch, tag, or commit (optional)
  },
  runtime: "node24",
  ports: [3000],
});
typescript
const sandbox = await Sandbox.create({
  source: {
    type: "git",
    url: "https://github.com/vercel/sandbox-example-next.git",
    depth: 1, // 浅克隆(可选)
    revision: "main", // 分支、标签或提交(可选)
  },
  runtime: "node24",
  ports: [3000],
});

With Private Git Repository

基于私有Git仓库

typescript
const sandbox = await Sandbox.create({
  source: {
    type: "git",
    url: "https://github.com/org/private-repo.git",
    username: process.env.GIT_USERNAME!,
    password: process.env.GIT_TOKEN!, // Use PAT for password
  },
  runtime: "node24",
});
typescript
const sandbox = await Sandbox.create({
  source: {
    type: "git",
    url: "https://github.com/org/private-repo.git",
    username: process.env.GIT_USERNAME!,
    password: process.env.GIT_TOKEN!, // 使用PAT作为密码
  },
  runtime: "node24",
});

From Tarball

基于压缩包

typescript
const sandbox = await Sandbox.create({
  source: {
    type: "tarball",
    url: "https://example.com/project.tar.gz",
  },
  runtime: "node24",
  ports: [3000],
});
typescript
const sandbox = await Sandbox.create({
  source: {
    type: "tarball",
    url: "https://example.com/project.tar.gz",
  },
  runtime: "node24",
  ports: [3000],
});

From Snapshot

基于快照

typescript
const sandbox = await Sandbox.create({
  source: {
    type: "snapshot",
    snapshotId: "snap_abc123",
  },
  ports: [3000],
});
typescript
const sandbox = await Sandbox.create({
  source: {
    type: "snapshot",
    snapshotId: "snap_abc123",
  },
  ports: [3000],
});

Auto-Dispose Pattern

自动销毁模式

Use
await using
for automatic cleanup:
typescript
async function runInSandbox() {
  await using sandbox = await Sandbox.create();
  // Sandbox automatically stopped when scope exits
  await sandbox.runCommand("echo", ["Hello"]);
}
使用
await using
实现自动清理:
typescript
async function runInSandbox() {
  await using sandbox = await Sandbox.create();
  // 沙箱会在作用域退出时自动停止
  await sandbox.runCommand("echo", ["Hello"]);
}

Running Commands

运行命令

Basic Command Execution

基础命令执行

typescript
const result = await sandbox.runCommand("npm", ["install"]);
if (result.exitCode !== 0) {
  console.error("Install failed:", await result.stderr());
}
typescript
const result = await sandbox.runCommand("npm", ["install"]);
if (result.exitCode !== 0) {
  console.error("安装失败:", await result.stderr());
}

With Options

带选项的命令

typescript
const result = await sandbox.runCommand({
  cmd: "npm",
  args: ["run", "build"],
  cwd: "/vercel/sandbox/app",
  env: { NODE_ENV: "production" },
  sudo: false,
  stdout: process.stdout, // Stream output
  stderr: process.stderr,
});
typescript
const result = await sandbox.runCommand({
  cmd: "npm",
  args: ["run", "build"],
  cwd: "/vercel/sandbox/app",
  env: { NODE_ENV: "production" },
  sudo: false,
  stdout: process.stdout, // 流式输出
  stderr: process.stderr,
});

Detached Commands (Background Processes)

分离命令(后台进程)

typescript
// Start dev server in background
const devServer = await sandbox.runCommand({
  cmd: "npm",
  args: ["run", "dev"],
  detached: true, // Returns immediately
  stdout: process.stdout,
});

// Later: wait for completion or kill
const finished = await devServer.wait();
// Supported signals: SIGHUP, SIGINT, SIGQUIT, SIGKILL, SIGTERM, SIGCONT, SIGSTOP (or numeric)
await devServer.kill("SIGTERM");
typescript
// 在后台启动开发服务器
const devServer = await sandbox.runCommand({
  cmd: "npm",
  args: ["run", "dev"],
  detached: true, // 立即返回
  stdout: process.stdout,
});

// 后续:等待完成或终止
const finished = await devServer.wait();
// 支持的信号:SIGHUP, SIGINT, SIGQUIT, SIGKILL, SIGTERM, SIGCONT, SIGSTOP(或数字)
await devServer.kill("SIGTERM");

Root Access

根权限

typescript
await sandbox.runCommand({
  cmd: "dnf",
  args: ["install", "-y", "golang"],
  sudo: true, // Execute as root
});
typescript
await sandbox.runCommand({
  cmd: "dnf",
  args: ["install", "-y", "golang"],
  sudo: true, // 以root身份执行
});

File Operations

文件操作

Write Files

写入文件

typescript
await sandbox.writeFiles([
  {
    path: "/vercel/sandbox/config.json",
    content: Buffer.from(JSON.stringify({ key: "value" })),
  },
  {
    path: "/vercel/sandbox/script.sh",
    content: Buffer.from("#!/bin/bash\necho 'Hello'"),
  },
]);
typescript
await sandbox.writeFiles([
  {
    path: "/vercel/sandbox/config.json",
    content: Buffer.from(JSON.stringify({ key: "value" })),
  },
  {
    path: "/vercel/sandbox/script.sh",
    content: Buffer.from("#!/bin/bash\necho 'Hello'"),
  },
]);

Read Files

读取文件

typescript
// Returns a Buffer object
const buffer = await sandbox.readFileToBuffer({
  path: "/vercel/sandbox/output.txt",
});

// Returns a NodeJS.ReadableStream
const stream = await sandbox.readFile({
  path: "/vercel/sandbox/large-file.bin",
});
typescript
// 返回Buffer对象
const buffer = await sandbox.readFileToBuffer({
  path: "/vercel/sandbox/output.txt",
});

// 返回NodeJS.ReadableStream
const stream = await sandbox.readFile({
  path: "/vercel/sandbox/large-file.bin",
});

Download Files

下载文件

typescript
const localPath = await sandbox.downloadFile(
  { path: "/vercel/sandbox/report.pdf" }, // source path on the sandbox
  { path: "./downloads/report.pdf" }, // destination path on the local machine
  { mkdirRecursive: true },
);
typescript
const localPath = await sandbox.downloadFile(
  { path: "/vercel/sandbox/report.pdf" }, // 沙箱中的源路径
  { path: "./downloads/report.pdf" }, // 本地机器的目标路径
  { mkdirRecursive: true },
);

Create Directories

创建目录

typescript
await sandbox.mkDir("/vercel/sandbox/my-app/src");
typescript
await sandbox.mkDir("/vercel/sandbox/my-app/src");

Network Policy

网络策略

Full Internet Access (Default)

完全互联网访问(默认)

typescript
const sandbox = await Sandbox.create({
  networkPolicy: "allow-all",
});
typescript
const sandbox = await Sandbox.create({
  networkPolicy: "allow-all",
});

No Network Access

禁止网络访问

typescript
const sandbox = await Sandbox.create({
  networkPolicy: "deny-all",
});
typescript
const sandbox = await Sandbox.create({
  networkPolicy: "deny-all",
});

Restricted Access (Simple Domain List)

受限访问(简单域名列表)

typescript
const sandbox = await Sandbox.create({
  networkPolicy: {
    allow: ["*.npmjs.org", "github.com", "registry.yarnpkg.com"],
    subnets: {
      allow: ["10.0.0.0/8"],
      deny: ["10.1.0.0/16"], // Takes precedence over allowed
    },
  },
});

// Update policy at runtime
await sandbox.updateNetworkPolicy({
  allow: ["api.openai.com"],
});
typescript
const sandbox = await Sandbox.create({
  networkPolicy: {
    allow: ["*.npmjs.org", "github.com", "registry.yarnpkg.com"],
    subnets: {
      allow: ["10.0.0.0/8"],
      deny: ["10.1.0.0/16"], // 优先级高于允许列表
    },
  },
});

// 在运行时更新策略
await sandbox.updateNetworkPolicy({
  allow: ["api.openai.com"],
});

Restricted Access with Credential Brokering

带凭证代理的受限访问

typescript
const sandbox = await Sandbox.create({
  networkPolicy: {
    allow: {
      "ai-gateway.vercel.sh": [
        {
          transform: [
            {
              headers: { authorization: "Bearer ..." },
            },
          ],
        },
      ],
      "*": [], // Allow all other domains without transforms
    },
  },
});
typescript
const sandbox = await Sandbox.create({
  networkPolicy: {
    allow: {
      "ai-gateway.vercel.sh": [
        {
          transform: [
            {
              headers: { authorization: "Bearer ..." },
            },
          ],
        },
      ],
      "*": [], // 允许所有其他域名不经过转换
    },
  },
});

Snapshots

快照

Snapshots save the entire sandbox filesystem to be reused later on, for any number of sandboxes.
快照会保存整个沙箱文件系统,以便后续重复使用,可用于任意数量的沙箱。

Create a Snapshot

创建快照

typescript
const sandbox = await Sandbox.create({ runtime: "node24" });

// Install dependencies
await sandbox.runCommand("npm", ["install"]);

// Create snapshot (stops the sandbox)
const snapshot = await sandbox.snapshot({
  expiration: ms("14d"), // Default: 30 days, use 0 for no expiration
});
console.log("Snapshot ID:", snapshot.snapshotId);
typescript
const sandbox = await Sandbox.create({ runtime: "node24" });

// 安装依赖
await sandbox.runCommand("npm", ["install"]);

// 创建快照(会停止沙箱)
const snapshot = await sandbox.snapshot({
  expiration: ms("14d"), // 默认:30天,设为0表示永不过期
});
console.log("快照ID:", snapshot.snapshotId);

List and Manage Snapshots

列出和管理快照

typescript
// List snapshots
const { snapshots, pagination } = await Snapshot.list();

// Get a specific snapshot
const snapshot = await Snapshot.get({ snapshotId: "snap_abc123" });

// Delete snapshot
await snapshot.delete();
typescript
// 列出快照
const { snapshots, pagination } = await Snapshot.list();

// 获取特定快照
const snapshot = await Snapshot.get({ snapshotId: "snap_abc123" });

// 删除快照
await snapshot.delete();

Exposed Ports

暴露端口

typescript
const sandbox = await Sandbox.create({
  ports: [3000, 8080],
});

// Get public URL for a port
const url = sandbox.domain(3000);
// Returns: https://subdomain.vercel.run

// Open in browser
spawn("open", [url]);
typescript
const sandbox = await Sandbox.create({
  ports: [3000, 8080],
});

// 获取端口的公开URL
const url = sandbox.domain(3000);
// 返回:https://subdomain.vercel.run

// 在浏览器中打开
spawn("open", [url]);

Timeout Management

超时管理

typescript
const sandbox = await Sandbox.create({
  timeout: ms("10m"), // Initial timeout, default of 5 minutes
});

// Extend timeout by 5 more minutes
await sandbox.extendTimeout(ms("5m"));
// New total: 15 minutes
typescript
const sandbox = await Sandbox.create({
  timeout: ms("10m"), // 初始超时,默认5分钟
});

// 延长超时5分钟
await sandbox.extendTimeout(ms("5m"));
// 新总时长:15分钟

Authentication

身份验证

Vercel OIDC Token (Recommended)

Vercel OIDC令牌(推荐)

bash
undefined
bash
undefined

Pull development credentials

获取开发凭证

vercel link vercel env pull

The SDK automatically uses `VERCEL_OIDC_TOKEN` from environment.
vercel link vercel env pull

SDK会自动使用环境变量中的`VERCEL_OIDC_TOKEN`。

Access Token (Alternative)

访问令牌(替代方案)

typescript
const sandbox = await Sandbox.create({
  teamId: process.env.VERCEL_TEAM_ID!,
  projectId: process.env.VERCEL_PROJECT_ID!,
  token: process.env.VERCEL_TOKEN!,
  // ... other options
});
typescript
const sandbox = await Sandbox.create({
  teamId: process.env.VERCEL_TEAM_ID!,
  projectId: process.env.VERCEL_PROJECT_ID!,
  token: process.env.VERCEL_TOKEN!,
  // ... 其他选项
});

Error Handling

错误处理

typescript
import { APIError, StreamError } from "@vercel/sandbox";

try {
  const sandbox = await Sandbox.create();
} catch (error) {
  if (error instanceof APIError) {
    console.error("API Error:", error.message, error.statusCode);
  } else if (error instanceof StreamError) {
    console.error("Stream Error:", error.message);
  }
  throw error;
}
typescript
import { APIError, StreamError } from "@vercel/sandbox";

try {
  const sandbox = await Sandbox.create();
} catch (error) {
  if (error instanceof APIError) {
    console.error("API错误:", error.message, error.statusCode);
  } else if (error instanceof StreamError) {
    console.error("流错误:", error.message);
  }
  throw error;
}

Cancellation with AbortSignal

使用AbortSignal取消操作

typescript
const controller = new AbortController();

// Cancel after 30 seconds
setTimeout(() => controller.abort(), 30000);

const sandbox = await Sandbox.create({
  signal: controller.signal,
});

const result = await sandbox.runCommand({
  cmd: "npm",
  args: ["test"],
  signal: controller.signal,
});
typescript
const controller = new AbortController();

// 30秒后取消
setTimeout(() => controller.abort(), 30000);

const sandbox = await Sandbox.create({
  signal: controller.signal,
});

const result = await sandbox.runCommand({
  cmd: "npm",
  args: ["test"],
  signal: controller.signal,
});

Limitations

限制

LimitationDetails
Max vCPUs8 vCPUs (2048 MB RAM per vCPU)
Max ports15 exposed ports
Max timeout5 hours (Pro/Enterprise), 45 minutes (Hobby)
Default timeout5 minutes
Base systemAmazon Linux 2023
User context
vercel-sandbox
user
Writable path
/vercel/sandbox
限制项详情
最大vCPU数8个vCPU(每个vCPU对应2048 MB内存)
最大端口数15个暴露端口
最大超时时间5小时(专业版/企业版),45分钟(免费版)
默认超时时间5分钟
基础系统Amazon Linux 2023
用户上下文
vercel-sandbox
用户
可写入路径
/vercel/sandbox

System Packages

系统包

Pre-installed:
git
,
tar
,
gzip
,
unzip
,
curl
,
openssl
,
procps
,
findutils
,
which
.
Install additional packages with sudo:
typescript
await sandbox.runCommand({
  cmd: "dnf",
  args: ["install", "-y", "package-name"],
  sudo: true,
});
预安装包:
git
,
tar
,
gzip
,
unzip
,
curl
,
openssl
,
procps
,
findutils
,
which
使用sudo安装额外包:
typescript
await sandbox.runCommand({
  cmd: "dnf",
  args: ["install", "-y", "package-name"],
  sudo: true,
});

CLI Quick Reference

CLI快速参考

bash
undefined
bash
undefined

Install CLI

安装CLI

pnpm i -g sandbox
pnpm i -g sandbox

Login / Logout

登录/登出

sandbox login sandbox logout
sandbox login sandbox logout

Create and connect

创建并连接

sandbox create --connect
sandbox create --connect

List sandboxes

列出沙箱

sandbox ls
sandbox ls

Execute command

执行命令

sandbox exec <sandbox-id> -- npm install
sandbox exec <sandbox-id> -- npm install

Run a command in a new sandbox (create + exec in one step)

在新沙箱中运行命令(一步完成创建+执行)

sandbox run -- node -e "console.log('hello')"
sandbox run -- node -e "console.log('hello')"

Start an interactive shell

启动交互式shell

sandbox connect <sandbox-id>
sandbox connect <sandbox-id>

Copy files

复制文件

sandbox cp local-file.txt <sandbox-id>:/vercel/sandbox/
sandbox cp local-file.txt <sandbox-id>:/vercel/sandbox/

Stop sandbox

停止沙箱

sandbox stop <sandbox-id>
sandbox stop <sandbox-id>

Snapshots

快照操作

sandbox snapshot <sandbox-id> sandbox snapshots ls sandbox snapshots get <snapshot-id> sandbox snapshots rm <snapshot-id>
sandbox snapshot <sandbox-id> sandbox snapshots ls sandbox snapshots get <snapshot-id> sandbox snapshots rm <snapshot-id>

Update network policy

更新网络策略

sandbox config network-policy <sandbox-id> --network-policy deny-all
undefined
sandbox config network-policy <sandbox-id> --network-policy deny-all
undefined

Common Patterns

常见模式

Dev Server Pattern

开发服务器模式

typescript
const sandbox = await Sandbox.create({
  source: { type: "git", url: "https://github.com/org/repo.git" },
  ports: [3000],
  timeout: ms("30m"),
});

await sandbox.runCommand("npm", ["install"]);
await sandbox.runCommand({ cmd: "npm", args: ["run", "dev"], detached: true });

// Wait for server to start
await new Promise((r) => setTimeout(r, 2000));
console.log("App running at:", sandbox.domain(3000));
typescript
const sandbox = await Sandbox.create({
  source: { type: "git", url: "https://github.com/org/repo.git" },
  ports: [3000],
  timeout: ms("30m"),
});

await sandbox.runCommand("npm", ["install"]);
await sandbox.runCommand({ cmd: "npm", args: ["run", "dev"], detached: true });

// 等待服务器启动
await new Promise((r) => setTimeout(r, 2000));
console.log("应用运行地址:", sandbox.domain(3000));

Build and Test Pattern

构建与测试模式

typescript
await using sandbox = await Sandbox.create({
  source: { type: "git", url: repoUrl },
});

const install = await sandbox.runCommand("npm", ["ci"]);
if (install.exitCode !== 0) throw new Error("Install failed");

const build = await sandbox.runCommand("npm", ["run", "build"]);
if (build.exitCode !== 0) throw new Error("Build failed");

const test = await sandbox.runCommand("npm", ["test"]);
process.exit(test.exitCode);
typescript
await using sandbox = await Sandbox.create({
  source: { type: "git", url: repoUrl },
});

const install = await sandbox.runCommand("npm", ["ci"]);
if (install.exitCode !== 0) throw new Error("安装失败");

const build = await sandbox.runCommand("npm", ["run", "build"]);
if (build.exitCode !== 0) throw new Error("构建失败");

const test = await sandbox.runCommand("npm", ["test"]);
process.exit(test.exitCode);

Snapshot Warm Start Pattern

快照预热启动模式

typescript
// First time: create snapshot with dependencies installed
async function createBaseSnapshot() {
  const sandbox = await Sandbox.create({ runtime: "node24" });
  await sandbox.runCommand("npm", ["install", "-g", "typescript", "tsx"]);
  const snapshot = await sandbox.snapshot();
  return snapshot.snapshotId;
}

// Subsequent runs: fast start from snapshot
async function runFromSnapshot(snapshotId: string, code: string) {
  await using sandbox = await Sandbox.create({
    source: { type: "snapshot", snapshotId },
  });
  await sandbox.writeFiles([
    { path: "/vercel/sandbox/index.ts", content: Buffer.from(code) },
  ]);
  return sandbox.runCommand("tsx", ["index.ts"]);
}
typescript
// 首次执行:创建已安装依赖的快照
async function createBaseSnapshot() {
  const sandbox = await Sandbox.create({ runtime: "node24" });
  await sandbox.runCommand("npm", ["install", "-g", "typescript", "tsx"]);
  const snapshot = await sandbox.snapshot();
  return snapshot.snapshotId;
}

// 后续执行:从快照快速启动
async function runFromSnapshot(snapshotId: string, code: string) {
  await using sandbox = await Sandbox.create({
    source: { type: "snapshot", snapshotId },
  });
  await sandbox.writeFiles([
    { path: "/vercel/sandbox/index.ts", content: Buffer.from(code) },
  ]);
  return sandbox.runCommand("tsx", ["index.ts"]);
}

Beta: Persistent Sandboxes (
@vercel/sandbox@beta
and
sandbox@beta
)

测试版:持久化沙箱(
@vercel/sandbox@beta
sandbox@beta

The beta introduces persistent, long-lived sandboxes with a new Session layer. Install with:
bash
pnpm i @vercel/sandbox@beta  # SDK 2.0.0-beta.x
pnpm i -g sandbox@beta       # CLI 3.0.0-beta.x
IMPORTANT:
  • This is a beta, not a stable version. Do not use for production.
  • If the user had installed a previous major version (
    @vercel/sandbox@1
    ,
    sandbox@1
    ,
    sandbox@2
    ), make it clear that sandboxes are by default persistent: they will automatically create snapshots to preserve the state.
测试版引入了带有新Session层的持久化、长期运行沙箱。安装方式:
bash
pnpm i @vercel/sandbox@beta  # SDK 2.0.0-beta.x
pnpm i -g sandbox@beta       # CLI 3.0.0-beta.x
重要提示:
  • 这是测试版,非稳定版本。请勿用于生产环境。
  • 如果用户已安装过旧主版本(
    @vercel/sandbox@1
    ,
    sandbox@1
    ,
    sandbox@2
    ),需明确告知:沙箱默认是持久化的,它们会自动创建快照以保留状态。

Key Concepts

核心概念

  • Sandbox = a persistent, named entity that survives across multiple VM boots.
  • Session = a running VM instance within a sandbox. Sessions are created/resumed automatically and are identified by ID.
  • Sandboxes are identified by name (not ID). Names are unique per project.
  • When a sandbox stops, it will automatically snapshot and restore the state on the next resume (with
    persistent: true
    , the default).
  • Migration: Old V1 sandboxes are backfilled with
    sandboxId
    as their
    name
    (e.g.,
    sbx_123
    ), so the only change needed is using
    name
    instead of
    sandboxId
    .
  • Sandbox = 持久化的命名实体,可跨多个VM启动存活。
  • Session = 沙箱内的运行VM实例。Session会自动创建/恢复,并通过ID标识。
  • 沙箱通过名称(而非ID)标识。名称在每个项目中唯一。
  • 当沙箱停止时,若设置
    persistent: true
    (默认值),会自动创建快照,并在下次恢复时还原状态。
  • 迁移:旧版V1沙箱会自动以
    sandboxId
    作为
    name
    (例如
    sbx_123
    ),因此只需将
    sandboxId
    替换为
    name
    即可。

New Exports

新增导出

typescript
import { Session } from "@vercel/sandbox";
typescript
import { Session } from "@vercel/sandbox";

Migration from Stable (
1.x
) to Beta (
2.x
)

从稳定版(1.x)迁移到测试版(2.x)

Creating sandboxes — new
name
and
persistent
params

创建沙箱 — 新增
name
persistent
参数

typescript
// Stable (1.x): anonymous, ephemeral sandboxes identified by sandboxId
const sandbox = await Sandbox.create({ runtime: "node24" });
console.log(sandbox.sandboxId);

// Beta (2.x): persistent sandboxes identified by name
const sandbox = await Sandbox.create({
  name: "my-dev-env", // Optional, random if omitted. Unique per project.
  runtime: "node24",
  persistent: true, // Default: true. Auto-snapshots on shutdown and restores on resume.
  snapshotExpiration: ms("7d"), // Optional. Default TTL for snapshots. Use 0 for no expiration.
});
console.log(sandbox.name);
typescript
// 稳定版(1.x):匿名、临时沙箱,通过sandboxId标识
const sandbox = await Sandbox.create({ runtime: "node24" });
console.log(sandbox.sandboxId);

// 测试版(2.x):持久化沙箱,通过名称标识
const sandbox = await Sandbox.create({
  name: "my-dev-env", // 可选,若省略则随机生成。每个项目中唯一。
  runtime: "node24",
  persistent: true, // 默认:true。关闭时自动快照,恢复时自动还原。
  snapshotExpiration: ms("7d"), // 可选。快照默认过期时间。设为0表示永不过期。
});
console.log(sandbox.name);

Retrieving sandboxes —
name
replaces
sandboxId

获取沙箱 —
name
替代
sandboxId

typescript
// Stable (1.x)
const sandbox = await Sandbox.get({ sandboxId: "sbx_abc123" });

// Beta (2.x) — retrieves by name.
const sandbox = await Sandbox.get({ name: "my-dev-env" });
// Pass `resume: true` to to automatically resume the sandbox. Otherwise, it will
// be resumed when the next command is run.
const sandbox = await Sandbox.get({ name: "my-dev-env", resume: false });
typescript
// 稳定版(1.x)
const sandbox = await Sandbox.get({ sandboxId: "sbx_abc123" });

// 测试版(2.x)— 通过名称获取。
const sandbox = await Sandbox.get({ name: "my-dev-env" });
// 传入`resume: true`可自动恢复沙箱。否则,会在下次运行命令时自动恢复。
const sandbox = await Sandbox.get({ name: "my-dev-env", resume: false });

Listing sandboxes — pagination and filtering changes

列出沙箱 — 分页和过滤方式变更

typescript
// Stable (1.x): used since/until for pagination
const {
  json: { sandboxes },
} = await Sandbox.list({ since, until });

// Beta (2.x): cursor-based pagination, new filtering params
const { sandboxes, pagination } = await Sandbox.list({
  cursor: pagination.next, // string token (replaces since/until)
  namePrefix: "my-app-", // Filter by name prefix
  sortBy: "name", // "createdAt" (default) or "name"
});
typescript
// 稳定版(1.x):使用since/until进行分页
const {
  json: { sandboxes },
} = await Sandbox.list({ since, until });

// 测试版(2.x):基于游标分页,新增过滤参数
const { sandboxes, pagination } = await Sandbox.list({
  cursor: pagination.next, // 字符串令牌(替代since/until)
  namePrefix: "my-app-", // 按名称前缀过滤
  sortBy: "name", // "createdAt"(默认)或"name"
});

Listing snapshots — new
name
filter

列出快照 — 新增
name
过滤器

typescript
// Beta (2.x): filter snapshots by sandbox name
const { snapshots } = await Snapshot.list({
  name: "my-dev-env", // Only snapshots belonging to this sandbox
});
typescript
// 测试版(2.x):按沙箱名称过滤快照
const { snapshots } = await Snapshot.list({
  name: "my-dev-env", // 仅显示属于该沙箱的快照
});

Auto-resume for persistent sandboxes

持久化沙箱的自动恢复

If a sandbox created with
persistent: true
is stopped, and you call
runCommand
,
writeFiles
, or similar SDK methods with the same sandbox name, the SDK automatically starts a new session and retries the operation. You do not need to resume manually.
若使用
persistent: true
创建的沙箱已停止,当你调用
runCommand
writeFiles
或类似SDK方法并指定相同沙箱名称时,SDK会自动启动新Session并重试操作。无需手动恢复。

New
Session
class

新增
Session

typescript
// Access the current running VM session
const session = sandbox.currentSession();
console.log(session.sessionId);
console.log(session.status); // "pending" | "running" | "stopping" | "stopped" | ...
typescript
// 获取当前运行的VM会话
const session = sandbox.currentSession();
console.log(session.sessionId);
console.log(session.status); // "pending" | "running" | "stopping" | "stopped" | ...

New
sandbox.update()
method (replaces
updateNetworkPolicy
)

新增
sandbox.update()
方法(替代
updateNetworkPolicy

typescript
// Stable (1.x)
await sandbox.updateNetworkPolicy("deny-all");

// Beta (2.x) — updateNetworkPolicy still works but is deprecated
await sandbox.update({
  networkPolicy: "deny-all",
  persistent: false,
  resources: { vcpus: 4 },
  timeout: ms("30m"),
  snapshotExpiration: ms("14d"), // Update default snapshot TTL. Use 0 for no expiration.
});
typescript
// 稳定版(1.x)
await sandbox.updateNetworkPolicy("deny-all");

// 测试版(2.x)— updateNetworkPolicy仍可用但已废弃
await sandbox.update({
  networkPolicy: "deny-all",
  persistent: false,
  resources: { vcpus: 4 },
  timeout: ms("30m"),
  snapshotExpiration: ms("14d"), // 更新快照默认过期时间。设为0表示永不过期。
});

New
sandbox.delete()
method

新增
sandbox.delete()
方法

typescript
// Permanently remove a sandbox and all its snapshots
await sandbox.delete();
typescript
// 永久删除沙箱及其所有快照
await sandbox.delete();

New
sandbox.listSessions()
and
sandbox.listSnapshots()

新增
sandbox.listSessions()
sandbox.listSnapshots()

typescript
// List all VM sessions for this sandbox
const sessions = await sandbox.listSessions();

// List snapshots belonging to this sandbox
const snapshots = await sandbox.listSnapshots();
typescript
// 列出该沙箱的所有VM会话
const sessions = await sandbox.listSessions();

// 列出属于该沙箱的快照
const snapshots = await sandbox.listSnapshots();

CLI Changes (3.0.0-beta)

CLI变更(3.0.0-beta)

Key differences from the stable CLI:
  • All commands now use sandbox name instead of sandbox ID.
  • sandbox rm
    /
    sandbox remove
    permanently deletes the sandbox.
  • New:
    sandbox sessions
    command to manage sessions.
  • New:
    sandbox create --name <name>
    to set a sandbox name.
  • New:
    sandbox create --snapshot-expiration <duration|none>
    to set default snapshot TTL.
  • New:
    sandbox create --non-persistent
    to disable state persistence.
  • New:
    sandbox run --stop
    to stop the session when the command exits.
  • New:
    sandbox run --name <name>
    resumes from an existing sandbox if it exists.
  • Breaking:
    sandbox run --rm
    now deletes the sandbox (previously just stopped it).
  • New:
    sandbox snapshots list --name <name>
    to filter snapshots by sandbox name.
  • New:
    sandbox config list <name>
    to view sandbox configuration.
  • New:
    sandbox config vcpus <name> <count>
    to update vCPUs.
  • New:
    sandbox config timeout <name> <duration>
    to update timeout.
  • New:
    sandbox config persistent <name> <true|false>
    to toggle persistence.
  • New:
    sandbox config snapshot-expiration <name> <duration|none>
    to set default snapshot TTL.
  • sandbox cp
    now uses
    <sandbox_name>:path
    instead of
    <sandbox_id>:path
    .
  • sandbox ls
    supports
    --name-prefix
    and
    --sort-by
    filtering.
与稳定版CLI的主要差异:
  • 所有命令现在使用沙箱名称而非沙箱ID。
  • sandbox rm
    /
    sandbox remove
    永久删除沙箱。
  • 新增:
    sandbox sessions
    命令用于管理会话。
  • 新增:
    sandbox create --name <name>
    设置沙箱名称。
  • 新增:
    sandbox create --snapshot-expiration <duration|none>
    设置快照默认过期时间。
  • 新增:
    sandbox create --non-persistent
    禁用状态持久化。
  • 新增:
    sandbox run --stop
    在命令退出时停止会话。
  • 新增:
    sandbox run --name <name>
    若沙箱已存在则从其恢复。
  • 破坏性变更:
    sandbox run --rm
    现在会删除沙箱(之前仅停止沙箱)。
  • 新增:
    sandbox snapshots list --name <name>
    按沙箱名称过滤快照。
  • 新增:
    sandbox config list <name>
    查看沙箱配置。
  • 新增:
    sandbox config vcpus <name> <count>
    更新vCPU数量。
  • 新增:
    sandbox config timeout <name> <duration>
    更新超时时间。
  • 新增:
    sandbox config persistent <name> <true|false>
    切换持久化状态。
  • 新增:
    sandbox config snapshot-expiration <name> <duration|none>
    设置快照默认过期时间。
  • sandbox cp
    现在使用
    <sandbox_name>:path
    而非
    <sandbox_id>:path
  • sandbox ls
    支持
    --name-prefix
    --sort-by
    过滤。