run
run executes untrusted JavaScript and type-stripped TypeScript in a hardened
QuickJS sandbox. Guest code can access only the host functions you provide.
Quick start
pnpm add runSupports Node.js 22.13 or newer and Bun.
import { run } from 'run';
const result = await run({
source: `
const orders = await store.listOrders('customer_123');
return orders.reduce((total, order) => total + order.amount, 0);
`,
hostFunctions: {
store: {
listOrders: (customerId: string) =>
database.orders.findMany({ customerId }),
},
},
});
if (result.status === 'completed') {
console.log(result.value);
}The generated program can call store.listOrders(), while the database client
and its credentials stay in your application.
Features
- Every invocation gets a fresh QuickJS context in a worker thread, with no ambient Node.js, filesystem, module, or network access.
- A host function can interrupt a run for approval or authentication. The run resumes without repeating host calls that already completed.
- Time, memory, result size, and concurrency are capped, per run or per runner.
run is for sandboxed JavaScript computation inside an application. Workloads
that need an operating system, package installation, or process-level isolation
should use Vercel Sandbox.
Documentation
Start with the introduction, then the foundations and the API reference.
Development
pnpm test:watch runs tests directly against TypeScript source, including the
embedded worker and guest serialization code. Source edits rerun affected tests
without a package build or a dist directory. Use pnpm --filter run test:node
for a single source test run.
pnpm test runs the source suite, then builds and runs the full suite against
the shipped worker bundle, including hardening and package distribution tests.
pnpm --filter run test:package (also test:hardening) runs this build-backed
suite directly. Bare vitest commands use the source setup; --mode package
selects the built worker and requires a package build first.
pnpm check runs formatting, static analysis, and the fail-closed banned-pattern
security scan. A local @banned-pattern-ignore is accepted only when it states
a concrete safety reason and suppresses an actual finding; stale suppressions
fail the scan.