| name | ref-vercel-sandbox |
| description | Reference for Vercel Sandbox SDK — ephemeral compute for executing untrusted code. Covers sandbox creation, file writing, command execution, and output retrieval. Consult when implementing the code execution engine. |
Vercel Sandbox Reference
Packages
bun add @vercel/sandbox
Latest: v1.9.0 (March 20, 2026)
Authentication
Requires a Vercel access token:
VERCEL_TOKEN=your_vercel_access_token
Or use Vercel OIDC token for automatic auth when deployed on Vercel.
Basic Workflow
import { Sandbox } from "@vercel/sandbox";
const sandbox = await Sandbox.create({
});
await sandbox.writeFiles([
{ path: "solution.js", content: Buffer.from(userCode) },
{ path: "test.js", content: Buffer.from(testHarness) },
]);
const command = await sandbox.runCommand("node test.js");
const stdout = await command.output("stdout");
const stderr = await command.output("stderr");
console.log(command.exitCode);
await sandbox.stop();
SDK API
Sandbox.create(options?)
const sandbox = await Sandbox.create({
timeout: 300000,
});
sandbox.writeFiles(files)
await sandbox.writeFiles([
{ path: "index.js", content: Buffer.from("console.log('hello');") },
{ path: "package.json", content: Buffer.from(JSON.stringify({ dependencies: { express: "^4.18.0" } })) },
{ path: "run.sh", content: Buffer.from("node index.js"), mode: 0o755 },
]);
sandbox.runCommand(command)
const cmd = await sandbox.runCommand("npm install && node index.js");
const stdout = await cmd.output("stdout");
const stderr = await cmd.output("stderr");
console.log(cmd.exitCode);
sandbox.readFile(path)
const content = await sandbox.readFile("output.json");
sandbox.domain()
const url = await sandbox.domain();
sandbox.stop()
await sandbox.stop();
For CodeGym: Code Execution Pattern
import { Sandbox } from "@vercel/sandbox";
async function executeUserCode(
userCode: string,
testHarness: string,
language: "javascript" | "typescript" | "python"
) {
const sandbox = await Sandbox.create();
try {
if (language === "javascript" || language === "typescript") {
await sandbox.writeFiles([
{ path: "solution.js", content: Buffer.from(userCode) },
{ path: "test.js", content: Buffer.from(testHarness) },
]);
const cmd = await sandbox.runCommand("node test.js");
return {
stdout: await cmd.output("stdout"),
stderr: await cmd.output(),
: cmd.,
: cmd. === ,
};
}
(language === ) {
sandbox.([
{ : , : .(userCode) },
{ : , : .(testHarness) },
]);
cmd = sandbox.();
{
: cmd.(),
: cmd.(),
: cmd.,
: cmd. === ,
};
}
} {
sandbox.();
}
}
System Specs
- Runtimes: node24, node22, python3.13
- Sudo: Available as
vercel-sandbox user
- Filesystem: Ephemeral — lost when sandbox stops
- Network: Available by default (can restrict with NetworkPolicy)
- Default timeout: 5 minutes
- Max timeout: 45 min (Hobby), 5 hours (Pro/Enterprise)
- Snapshots: Can snapshot a sandbox state and restore later
Gotchas
- VERCEL_TOKEN required — get from Vercel dashboard Settings > Tokens
- Cold start — first sandbox creation takes a few seconds
- Ephemeral filesystem — all files deleted when sandbox stops
- npm packages — need to
npm install inside the sandbox if you need deps
cmd.wait() — must await to get exitCode, otherwise it returns immediately
- Pricing — check Vercel Sandbox pricing; Hobby plan has limits
- Use for stretch goal — if Sandbox setup is blocked, fall back to in-browser execution with Function constructor or eval (for JS only)
Fallback: In-Browser Execution (No Sandbox)
For JS/TS only, if Sandbox is unavailable:
function executeInBrowser(userCode: string, testCode: string) {
try {
const fn = new Function(userCode + "\n" + testCode);
const result = fn();
return { passed: true, output: result };
} catch (error) {
return { passed: false, error: error.message };
}
}
This is less secure but works for a hackathon demo with JS problems only.