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.
bun add @vercel/sandbox
Latest: v1.9.0 (March 20, 2026)
Requires a Vercel access token:
VERCEL_TOKEN=your_vercel_access_token
Or use Vercel OIDC token for automatic auth when deployed on Vercel.
import { Sandbox } from "@vercel/sandbox";
// 1. Create a sandbox
const sandbox = await Sandbox.create({
// Optional: choose runtime image
// Available: node24, node22, python3.13
});
// 2. Write files to the sandbox
// writeFiles takes an array of {path, content: Buffer} objects (v1.9.0)
await sandbox.writeFiles([
{ path: "solution.js", content: Buffer.from(userCode) },
{ path: "test.js", content: Buffer.from(testHarness) },
]);
// 3. Run a command — returns CommandFinished directly (no .wait() needed)
const command = await sandbox.runCommand("node test.js");
// 4. Get output — output() takes a stream specifier
const stdout = await command.output("stdout");
const stderr = await command.output("stderr");
console.log(command.exitCode); // already populated on CommandFinished
// 5. Clean up (sandbox auto-stops on timeout)
await sandbox.stop();
const sandbox = await Sandbox.create({
// All optional
timeout: 300000, // 5 min default, max 45 min (Hobby)
});
// v1.9.0: takes an array of {path, content: Buffer, mode?} objects
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" } })) },
// Optional: set file permissions (e.g., executable)
{ path: "run.sh", content: Buffer.from("node index.js"), mode: 0o755 },
]);
// Returns CommandFinished directly — exitCode is already populated, no .wait() needed
const cmd = await sandbox.runCommand("npm install && node index.js");
const stdout = await cmd.output("stdout"); // "stdout" | "stderr" | "both"
const stderr = await cmd.output("stderr");
console.log(cmd.exitCode); // 0 = success
const content = await sandbox.readFile("output.json");
const url = await sandbox.domain(); // get public URL for HTTP server
await sandbox.stop();
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") {
// writeFiles takes an array of {path, content: Buffer} objects
await sandbox.writeFiles([
{ path: "solution.js", content: Buffer.from(userCode) },
{ path: "test.js", content: Buffer.from(testHarness) },
]);
// runCommand returns CommandFinished directly — exitCode already populated
const cmd = await sandbox.runCommand("node test.js");
return {
stdout: await cmd.output("stdout"),
stderr: await cmd.output("stderr"),
exitCode: cmd.exitCode,
passed: cmd.exitCode === 0,
};
}
if (language === "python") {
await sandbox.writeFiles([
{ path: "solution.py", content: Buffer.from(userCode) },
{ path: "test_solution.py", content: Buffer.from(testHarness) },
]);
const cmd = await sandbox.runCommand("python3 test_solution.py");
return {
stdout: await cmd.output("stdout"),
stderr: await cmd.output("stderr"),
exitCode: cmd.exitCode,
passed: cmd.exitCode === 0,
};
}
} finally {
await sandbox.stop();
}
}
vercel-sandbox usernpm install inside the sandbox if you need depscmd.wait() — must await to get exitCode, otherwise it returns immediatelyFor JS/TS only, if Sandbox is unavailable:
// Client-side execution using Function constructor
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.