@boxlite-ai/boxlite

中文文档
0.12.0发布于 2026/11/06Apache-2.0TypeScriptES Module零依赖构建来源已验证近 30 天下载 3万

BoxLite - 可嵌入的微VM运行时间用于安全,孤立的代码执行

中文使用文档
文档目录34 节
  1. 特征
  2. 安装
  3. 快速启动
  4. Java 脚本
  5. 类型脚本
  6. TypeScript 5.2+ (同步处理)
  7. API 参考
  8. 远程 BoxLite 服务器 (REST)
  9. 运行时登记选项
  10. 简单框
  11. 来宾 SSH 控制
  12. 运行时图像管理
  13. 私人登记登录
  14. 活期执行库存
  15. 代码框
  16. 浏览器框
  17. 计算机盒
  18. 交互式框
  19. 实例
  20. 处理错误
  21. 来源建筑
  22. 类型脚本支持
  23. 平台要求
  24. 马科斯
  25. 链接
  26. 建筑
  27. 业绩
  28. 解决问题
  29. 捐款
  30. 代理绑定测试
  31. 许可证
  32. 相关项目
  33. 支助
  34. 服务隧道

BoxLite 节点.js/ TypeScript SDK

可嵌入 VM 运行时间用于安全,孤立的代码执行环境.

进入 代理 API 结束 JsBox.agents 财务报告和审定财务报表 SimpleBox.agents 用于代理和转动方法、分组选项和错误处理.

想想"SQLite来沙盒" - 直接嵌入在应用程序中的轻量级库,而不需要守护进程或根权限.

npm version License: Apache 2.0

特征

  • 硬件级 VM 隔离 (KVM on Linux, Hypervisor. Framework on macOS) (韩语)
  • OCI 集装箱支持 - 使用任何 Docker/OCI 图像
  • Async 第一张API - 在土生土长的砂拉越上建造
  • 多个专用盒数字 :
    • SimpleBox - 基本命令执行
    • CodeBox - Python 密码沙盒
    • BrowserBox - 浏览器自动化(Puppeteer/Playwright)
    • ComputerBox - 桌面自动化(14个自动化功能)
    • InteractiveBox - PTY终端会话
  • 零守护进程 - 不需要背景过程
  • 跨平台 - macOS ARM64, Linux x86 64/ARM64

安装

npm install @boxlite-ai/boxlite

所需经费:

  • 节点.js 18或以后
  • 有硬件虚拟化的平台 :
    • macOS:苹果硅(macOS 12+)
    • Linux: x86 64 或 ARM64 有 KVM ()/dev/kvm 可访问)

不支持 : macOS Intel, Windows(使用带有Linux要求的WSL2)

快速启动

Java 脚本

import { SimpleBox } from '@boxlite-ai/boxlite';

async function main() {
  const box = new SimpleBox({ image: 'alpine:latest' });

  try {
    const result = await box.exec('echo', 'Hello from BoxLite!');
    console.log(result.stdout);  // Hello from BoxLite!
  } finally {
    await box.stop();
  }
}

main();

类型脚本

import { SimpleBox } from 'boxlite';

async function main() {
  const box = new SimpleBox({ image: 'alpine:latest' });

  try {
    const result = await box.exec('echo', 'Hello from BoxLite!');
    console.log(result.stdout);
  } finally {
    await box.stop();
  }
}

main();

TypeScript 5.2+ (同步处理)

import { SimpleBox } from 'boxlite';

async function main() {
  await using box = new SimpleBox({ image: 'alpine:latest' });
  const result = await box.exec('echo', 'Hello!');
  console.log(result.stdout);
  // Box automatically stopped when leaving scope
}

main();

API 参考

远程 BoxLite 服务器 (REST)

连接到远程 BoxLite 服务器而不是本地运行时间 . 构造一个 ApiKeyCredential 并呈递其位置: Boxlite.rest(url, credential)。 。 。 .

import { JsBoxlite, ApiKeyCredential } from '@boxlite-ai/boxlite';

const rt = JsBoxlite.rest(
  'http://localhost:8100',
  new ApiKeyCredential('your-api-key'),
);
const boxes = await rt.listInfo();

// Env discovery — returns null when BOXLITE_API_KEY is unset:
const cred = ApiKeyCredential.fromEnv();
const rt2 = JsBoxlite.rest('http://localhost:8100', cred ?? undefined);

ApiKeyCredential 结构满足导出 Credential 界面; 函数可以按 Credential 财务报告和审定财务报表 接受任何未来的证书类型而无需更改签名.

运行前缀( 复仇- 不可知)

框范围请求 {url}/v1/{prefix}/…编辑 v1 段为硬码; path_prefix 是不透明的,部署 - 服务器告诉客户端通过 Principal.path_prefix 从 GET /v1/me。槽的语义 专供供应商使用:盒式云为组织使用 id; 另一种部署可能使用工作空间名称, 区域+团队 ,或者任何其他多块值,例如 us-east/team-42。 。 。 .

import { JsBoxlite, BoxliteRestOptions, ApiKeyCredential } from '@boxlite-ai/boxlite';

const rt = JsBoxlite.rest(new BoxliteRestOptions({
  url: 'https://api.boxlite.ai',
  credential: new ApiKeyCredential('blk_live_…'),
  pathPrefix: 'acme',   // → requests hit /v1/acme/boxes
}));

何时 pathPrefix 未设置, 客户端将建立 URL 而不包含 部分( c)/v1/boxes/…)——单租户的犬形 部署人员,如当地 boxlite serve 参考服务器.

CLI 抓获 Principal.path_prefix 登录并缓存它 在活动剖面图下,因此 boxlite 命令路径 正确的没有额外的旗帜.

运行时登记选项

import { JsBoxlite } from 'boxlite';

const runtime = new JsBoxlite({
  imageRegistries: [
    {
      host: 'registry.example.com',
      auth: { username: 'user', password: 'password' },
    },
    {
      host: 'registry.local:5000',
      transport: 'http',
      search: true,
    },
  ],
});

简单框

命令执行的基本容器 .

import { SimpleBox } from 'boxlite';

const box = new SimpleBox({
  image: 'python:slim',
  memoryMib: 512,    // Memory limit in MiB
  cpus: 2,           // Number of CPU cores
  name: 'my-box',    // Optional name
  autoRemove: true,  // Auto-remove on stop (default: true)
  workingDir: '/app',
  network: {
    outbound: {
      mode: 'enabled',
      allowNet: ['api.openai.com'],
    },
    inbound: {
      mode: 'disabled',
    },
  },
  // The pre-split shape `network: { mode, allowNet }` still works and
  // configures the outbound direction. Passing it together with `outbound`
  // is rejected.
  advanced: {
    capabilities: {
      add: ['NET_ADMIN'],
      drop: ['NET_RAW'],
    },
  },
  env: { FOO: 'bar' },
  volumes: [
    // A host bind (local runtimes only)...
    { hostPath: '/tmp/data', guestPath: '/data', readOnly: false },
    // ...or a managed volume, by id or by name (REST runtimes).
    { managedVolume: 'my-data', guestPath: '/cache' }
  ],
  ports: [
    { hostPort: 8080, guestPort: 80 }
  ],
  secrets: [
    {
      name: 'openai',
      value: process.env.OPENAI_API_KEY!,
      hosts: ['api.openai.com'],
    }
  ]
});

// Execute command
const result = await box.exec('ls', '-la', '/');
console.log(result.exitCode, result.stdout, result.stderr);

// Execute with options (cwd, user, timeout)
const pwdResult = await box.exec('pwd', [], undefined, {
  cwd: '/tmp',
  user: 'nobody',
  timeoutSecs: 30,
});
console.log(pwdResult.stdout); // "/tmp\n"

// Get box info
console.log(box.id);    // ULID
console.log(box.name);  // Optional name
const info = await box.info(); // Metadata
// null means unknown to this handle; [] means no active publications.
console.log(info.network?.publishedPorts);
// Local info reads do not query the live network backend; REST info performs a GET.
const refreshed = await runtime.getInfo(box.id);
console.log(refreshed?.network?.publishedPorts);

// Cleanup
await box.stop();

info(), (中文(简体) ), getInfo(),以及 listInfo() 曝光 privileged,客机模式已保存 在创作。 地方元数据报告 true 或者说 false; 省略 REST 服务器 字段生成 undefined。 。 。 .

来宾 SSH 控制

JsBox 财务报告和审定财务报表 SimpleBox 曝光 box.ssh 配置、观察和禁用 嘉宾SSH听众.

import { readFile } from 'node:fs/promises';

const status = await box.ssh.configure({
  listenAddress: '0.0.0.0:2222',
  hostPrivateKey: await readFile('host_key', 'utf8'), // OpenSSH private key
  accounts: [
    {
      login: 'alice',
      authorizedKeys: [await readFile('alice.pub', 'utf8')],
      // Certificate auth instead of authorizedKeys:
      // ca: { publicKey: caPublicKey, principal: 'alice' },
    },
  ],
});
// { enabled: true, generation: 1n, listenAddress, hostPublicKey,
//   hostKeyFingerprint } — generation is a bigint (full u64).

await box.ssh.status();
await box.ssh.disable();
await box.ssh.enable(); // reuse saved configuration; requires a running box

见 节点.js SSH 参考 用于配置类型、返回值和出错.

运行时图像管理

runtime.images 保存运行时可启动的图像: 本地缓存 嵌入运行时间, 服务器的目录 JsBoxlite.rest(...)。同样的 代码对任意一种; pull 仅本地( REST 运行时间拉动当 框)和 usage, (中文(简体) ), createAlias 财务报告和审定财务报表 deleteAlias 仅是REST.

import { JsBoxlite } from "boxlite";

const runtime = JsBoxlite.withDefaultConfig();

const images = await runtime.images.list();
for (const image of images) {
  console.log(image.repository, image.tag, image.id);
}

const detail = await runtime.images.get("docker.io/library/alpine");
console.log(detail.aliases, detail.versions.map((version) => version.digest));
await runtime.images.remove("docker.io/library/alpine");

pull 提前填补本地缓存。 REST 运行时间拒绝作为 不支持, 因为创建框会拉动图像 :

const pulled = await runtime.images.pull("alpine:latest");
console.log(pulled.reference, pulled.configDigest, pulled.layerCount);

见 节点参考 每个运行时间的每种方法.

私人登记登录

打开 JsBoxlite.rest(...), (中文(简体) ), runtime.images.registries 管理服务器的登录 绘制私人图像。 密码升起一次,再也没有回回. 本地运行时间抛出 unsupported: 通过 imageRegistries 备选案文 换句话说.

const login = await runtime.images.registries.create({
  registryHost: "ghcr.io",
  repositoryPrefix: "acme/", // omit for the whole registry
  username: "acme-bot",
  password: process.env.GHCR_TOKEN!,
});
const box = await runtime.create({ image: "ghcr.io/acme/private-app:1" });
// ...
await runtime.images.registries.remove(login.id); // refused while a box pulls through it

见 节点参考。 。 。 .

活期执行库存

await box.executions().list() 当地人提供 JsBox 财务报告和审定财务报表 SimpleBox。 。 。 . 它回来了 ExecutionInfo[] 从嘉宾的现场盘点,包括 主要进程: executionId (嘉宾身份), argv, (中文(简体) ), startedAt (一分九秒), tty,以及 isMainSession。完成的进程消失;此 不是执行历史。 列表不附加或消耗输出, 永远不会 靴子一个停止的盒子。 停止/ 未启动的本地框返回空列表; a 暂停框返回无效状态错误。 未创建 SimpleBox (单位:千美元) 返回空列表而不创建其框.

使用 await box.executions().get(executionId) 仅限控制访问,而 另一个客户端拥有输出,或 await box.executions().attach(executionId, false) 以恢复溪流,而无需 stdin。 两者均可在本地 JsBox 财务报告和审定财务报表 SimpleBox,永远不要启动盒子,然后返回一个 JsExecution 支助 kill(), (中文(简体) ), signal(),以及 wait()。只允许一个输出读取器.

for (const execution of await box.executions().list()) {
  console.log(execution.executionId, execution.argv, execution.isMainSession);
}

代码框

Python代码执行沙盒.

import { CodeBox } from 'boxlite';

const codebox = new CodeBox({
  image: 'python:slim',  // default
  memoryMib: 512,
  cpus: 1
});

try {
  // Run Python code
  const result = await codebox.run(`
import math
print(f"Pi is approximately {math.pi}")
  `);
  console.log(result);  // Pi is approximately 3.141592653589793

  // Install packages
  await codebox.installPackage('requests');
  await codebox.installPackages('numpy', 'pandas');

  // Use installed packages
  const result2 = await codebox.run(`
import requests
response = requests.get('https://api.github.com/zen')
print(response.text)
  `);
  console.log(result2);
} finally {
  await codebox.stop();
}

浏览器框

有远程调试的浏览器自动化 .

import { BrowserBox } from 'boxlite';

const browser = new BrowserBox({
  browser: 'chromium',  // 'chromium', 'firefox', or 'webkit'
  memoryMib: 2048,
  cpus: 2
});

try {
  await browser.start();

  // Get CDP endpoint
  const endpoint = browser.endpoint();
  console.log(endpoint);  // http://localhost:9222

  // Connect with Puppeteer
  import puppeteer from 'puppeteer-core';
  const browserInstance = await puppeteer.connect({ browserURL: endpoint });

  const page = await browserInstance.newPage();
  await page.goto('https://example.com');
  const title = await page.title();
  console.log(title);

  await page.close();
} finally {
  await browser.stop();
}

计算机盒

具有网页访问功能的桌面自动化.

import { ComputerBox } from 'boxlite';

const desktop = new ComputerBox({
  cpus: 2,
  memoryMib: 2048,
  guiHttpPort: 3000,   // default
  guiHttpsPort: 3001   // default (self-signed cert)
});

try {
  // Wait for desktop to be ready
  await desktop.waitUntilReady(60);

  // Mouse automation
  await desktop.mouseMove(100, 200);
  await desktop.leftClick();
  await desktop.doubleClick();
  await desktop.rightClick();
  await desktop.leftClickDrag(100, 100, 200, 200);

  const [x, y] = await desktop.cursorPosition();
  console.log(`Cursor at: ${x}, ${y}`);

  // Keyboard automation
  await desktop.type('Hello, World!');
  await desktop.key('Return');
  await desktop.key('ctrl+c');

  // Screenshot
  const screenshot = await desktop.screenshot();
  console.log(`${screenshot.width}x${screenshot.height} ${screenshot.format}`);
  // screenshot.data contains base64-encoded PNG

  // Scroll
  await desktop.scroll(500, 300, 'down', 5);

  // Get screen size
  const [width, height] = await desktop.getScreenSize();
  console.log(`Screen: ${width}x${height}`);

  // Access desktop via browser:
  // HTTP:  http://localhost:3000
  // HTTPS: https://localhost:3001 (self-signed certificate)
} finally {
  await desktop.stop();
}

交互式框

与 PTY 交互终端会话.

import { InteractiveBox } from 'boxlite';

const box = new InteractiveBox({
  image: 'alpine:latest',
  shell: '/bin/sh',
  tty: true,  // Auto-detected if undefined
  memoryMib: 512,
  cpus: 1
});

try {
  await box.start();
  await box.wait();  // Blocks until shell exits
} finally {
  await box.stop();
}

实例

见 ././实例/节点/ 完整示例目录 :

# If installed via npm
npm install @boxlite-ai/boxlite
node simplebox.js

# If working from source
cd ../../sdks/node
npm install && npm run build
npm link
cd ../../examples/node
npm link @boxlite-ai/boxlite
node simplebox.js

处理错误

import { SimpleBox, ExecError, TimeoutError, ParseError } from 'boxlite';

try {
  const box = new SimpleBox({ image: 'alpine:latest' });
  await box.exec('false');  // Exit code 1
} catch (err) {
  if (err instanceof ExecError) {
    console.error(`Command failed: ${err.command}`);
    console.error(`Exit code: ${err.exitCode}`);
    console.error(`Stderr: ${err.stderr}`);
  }
}

运行时间本身的失败 包含一个代码 errorCode(err) 返回,例如 not_found 或者说 invalid_state这是 undefined 用于任何 其他错误。 见 节点参考。 。 。 .

来源建筑

# Clone repository
git clone https://github.com/boxlite-ai/boxlite.git
cd boxlite/sdks/node

# Initialize submodules (critical!)
git submodule update --init --recursive

# Install dependencies
npm install

# Build (Rust + TypeScript)
npm run build

# Link to examples
npm link
cd ../../examples/node
npm link @boxlite-ai/boxlite

# Run examples
node simplebox.js

类型脚本支持

全部类型脚本支持包括:

import {
  SimpleBox, CodeBox, BrowserBox, ComputerBox, InteractiveBox,
  type SimpleBoxOptions,
  type CodeBoxOptions,
  type BrowserBoxOptions,
  type ComputerBoxOptions,
  type InteractiveBoxOptions,
  type Secret,
  type ExecResult,
  type Screenshot,
  type BrowserType
} from 'boxlite';

平台要求

马科斯

  • 苹果硅 (ARM64)
  • macOS 12+(蒙特雷或以后)
  • Hypervisor.framework (内建) (中文(简体) )

链接

  • x86 64或ARM64 导弹
  • KVM 已启用( O)/dev/kvm 可访问)
  • 用户在 kvm 组 :
    sudo usermod -aG kvm $USER
    # Logout/login required
    

建筑

SDK使用双层架构:

  1. 第1层( Rust): 绑定本地 BoxLite 运行时的 supi- rs

    • 直接映射到 Rust boxlite 条框
    • 通过Async操作 env.spawn() (无阻塞)
    • 通过同步执行器进行流程处理
  2. 第2层( TypeScript): 方便包装

    • 专用框类(CodeBox,浏览器Box等)
    • 错误等级
    • 输出收藏助手
    • 类型脚本类型定义

业绩

  • 启动时间: < 100ms
  • 间接对 Python SDK: < 5%
  • 并行框:受系统资源限制
  • 内存足迹: ~50-100MB 每盒(取决于图像)

解决问题

找不到 BoxLite 本地扩展名

  • 运行 npm run build 来编译 Rust 绑定

"没有找到影像"

  • 首次使用的 BoxLite 自动推出 OCI 图像
  • 确保互联网连接

"拒绝"(Linux)

  • 检查 KVM 访问 : ls -l /dev/kvm
  • 添加用户到 kvm 组 : sudo usermod -aG kvm $USER

"不支持的引擎"

  • 只有苹果硅Macs支持(不是英特尔)
  • 视窗用户:使用带有Linux要求的WSL2

捐款

见 ././ 捐款 发展准则.

代理绑定测试

从寄存器根运行 make test:integration:node FILTER='agent namespace'。本地的 Box 获取器测试 从回转的 REST 服务器获取一个手柄,并检查命名空间访问,而不包含 启动 VM 或发送代理请求。 单独测试拒绝纯对象和 在代理操作运行前只能使用原型方法接收器.

这些接收器测试练习了凝固汽油筒 调回未包装。 他们不锻炼 生成 FromNapiRef 财务报告和审定财务报表 FromNapiMutRef 由 CodeQL 标记的转换, 因此,通过它们并不能证明这些指针警告是虚假的阳性. 转换在锁定中生成 美洲狮后端。 。 。 .

许可证

Apache 2. 0 - 见 ././LICENSE

支助


由 BoxLite 实验室制作

服务隧道

使用内置地址 node:net 准备服务隧道:

import { SocketAddress } from "node:net";

const tunnel = await box.network.tunnel(
  new SocketAddress({ address: "127.0.0.1", port: 3000 }),
  { isPublic: false },
);

选项默认为公共;私人隧道需要云运行时间. IPv6目标 使用情况 new SocketAddress({ address: "::1", family: "ipv6", port: 3000 })。 。 。 . 目标必须有一个非零端口,一个回转或来宾IP,以及零流标签. 港口和旧的 { type: "tcp", ... } 目标被拒绝。 无效的参数 类型可以在本地网络控件上同步投放。 TCP/Unix 听器 形状仍然可用 tunnel.forward(listen)。 。 。 . 见 私人隧道。 。 。 .

版本与发布记录

@boxlite-ai/boxlite 共发布 43 个版本,首次发布于 2026/01/11;过去 12 个月发布了 43 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.12.0latest2026/11/061 天前
0.11.02026/10/309 天前
0.10.82026/10/2315 天前
0.10.72026/10/1821 天前
0.10.62026/10/1226 天前
0.10.52026/09/301 个月前

关于 @boxlite-ai/boxlite 的常见问题

@boxlite-ai/boxlite 是什么?

BoxLite - 可嵌入的微VM运行时间用于安全,孤立的代码执行

如何安装 @boxlite-ai/boxlite?

在项目目录运行 npm install @boxlite-ai/boxlite,或使用 pnpm add / yarn add / bun add。

@boxlite-ai/boxlite 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@boxlite-ai/boxlite 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@boxlite-ai/boxlite 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@boxlite-ai/boxlite 可以商用吗?

@boxlite-ai/boxlite 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@boxlite-ai/boxlite 的下载量有多少?

根据 npm 官方下载统计,@boxlite-ai/boxlite 在 2026/10/09 – 2026/11/07 这 30 天内被下载 30,013 次,日均约 1,000 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@boxlite-ai/boxlite 还在维护吗?

最新版本 0.12.0 发布于 2026/11/06(1 天前);至今共发布 43 个版本,其中过去 12 个月发布了 43 个;首次发布于 2026/01/11。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。