Skip to content
Runtime

How to run Bun code in a cloud sandbox

Bun 1.4.0 is preinstalled in every Runtime sandbox. Write your file into the microVM and run bun on it. TypeScript and tests work without extra setup.

On Runtime, Bun needs no install step, and the SDK runs on Bun too. Every sandbox is a Firecracker microVM with its own kernel. Bun 1.4.0 is installed next to Node.js 24.21.0. A 2 vCPU, 4 GiB sandbox costs $0.08 an hour with both CPUs busy, and $0.03125 an hour while it waits. Runtime bills the CPU your code uses (pricing).

Run a Bun script

TypeScriptimport { Sandbox } from "withruntime";const script = `const words = "the quick brown fox jumps over the lazy dog".split(" ");const longest: string = words.reduce((a, b) => (b.length > a.length ? b : a));console.log(longest, Bun.version);`;await using sbx = await Sandbox.create({  network: { internet: false },  timeoutSeconds: 300,  onLeaseEnd: "stop",});await sbx.files.write("/workspace/job.ts", script);const run = await sbx.exec(["bun", "job.ts"], { timeoutMs: 20_000 });console.log(run.exitCode, run.stdout);
Pythonfrom withruntime import Sandboxscript = """const words = "the quick brown fox jumps over the lazy dog".split(" ");const longest: string = words.reduce((a, b) => (b.length > a.length ? b : a));console.log(longest, Bun.version);"""with Sandbox.create(network={"internet": False}, timeout_seconds=300, on_lease_end="stop") as sbx:    sbx.files.write("/workspace/job.ts", script)    run = sbx.exec(["bun", "job.ts"], timeout_ms=20_000)    print(run.exit_code, run.stdout)

Bun "supports TypeScript and JSX with no configuration". It transpiles each file before it runs (Bun). Bun does not type-check. For tsc, see TypeScript in a sandbox.

What is in the image

Tool Version or detail
Bun 1.4.0 (bun)
Node.js 24.21.0 (node, npm, npx)
unzip In the image; Bun's own installer needs it on Linux
Build tools gcc, g++, make
OS Ubuntu 24.04.5 LTS (noble), amd64, 6.18 kernel

Commands run as the user runtime, with /workspace as the home and working directory. sudo works without a password (the sandbox environment).

Run a test suite with bun test

bun test is Bun's built-in runner, and it is compatible with Jest. It finds files named *.test.ts, *_test.ts, *.spec.ts and *_spec.ts, and the JavaScript forms of those names. Each test times out after 5,000 ms unless you pass --timeout (Bun test).

TypeScriptimport { Sandbox } from "withruntime";await using sbx = await Sandbox.create({ timeoutSeconds: 1200, onLeaseEnd: "stop" });await sbx.files.upload("./my-app", "/workspace/app");await sbx.exec("cd app && bun install", { check: true, timeoutMs: 300_000 });await sbx.network.set({ internet: false }); // tests run with no networkconst run = await sbx.exec(["bun", "test", "--timeout", "20000"], {  cwd: "/workspace/app",  timeoutMs: 600_000,  onStdout: (text) => process.stdout.write(text),});process.exitCode = run.exitCode ?? 1;
Pythonimport sysfrom withruntime import Sandboxwith Sandbox.create(timeout_seconds=1200, on_lease_end="stop") as sbx:    sbx.files.upload("./my-app", "/workspace/app")    sbx.exec("cd app && bun install", check=True, timeout_ms=300_000)    sbx.network.set(internet=False)  # tests run with no network    run = sbx.exec(["bun", "test", "--timeout", "20000"], cwd="/workspace/app",                   timeout_ms=600_000, on_stdout=sys.stdout.write)    sys.exit(1 if run.exit_code is None else run.exit_code)

With timeoutMs over 60 seconds, output streams, and the result keeps everything the tests printed. Cutting the network after the install keeps a test that calls out from reaching anything.

Serve a Bun app

Start a server with spawn, not exec. Everything that exec starts ends when its command ends. Then share the port as a private HTTPS preview.

TypeScriptimport { Sandbox } from "withruntime";await using sbx = await Sandbox.create({ timeoutSeconds: 1800 });await sbx.files.write(  "/workspace/server.ts",  'Bun.serve({ port: 3000, fetch: () => new Response("hello from bun") });',);const server = await sbx.spawn(["bun", "server.ts"]);await sbx.exec("sleep 1 && curl -s localhost:3000", { check: true });console.log(server.id);

A newer Bun, or the same Bun in every sandbox

Bun's installer puts Bun in ~/.bun/bin. It takes a version as bash -s "bun-v<version>", and it needs unzip (Bun installation). To pin one release for every sandbox, run the installer in a custom image recipe. Set BUN_INSTALL to /usr/local, so bun lands on the sandbox user's PATH:

TypeScriptimport { Runtime } from "withruntime";const runtime = new Runtime();await runtime.images.build({  name: "bun-app",  recipe: {    commands: ["curl -fsSL https://bun.com/install | BUN_INSTALL=/usr/local bash"],    npm: ["zod"],  },});await using sbx = await runtime.sandboxes.create({ image: "bun-app" });console.log((await sbx.exec(["bun", "--version"])).stdout);
Pythonfrom withruntime import Runtimeruntime = Runtime()runtime.images.build(name="bun-app", recipe={    "commands": ["curl -fsSL https://bun.com/install | BUN_INSTALL=/usr/local bash"],    "npm": ["zod"],})with runtime.sandboxes.create(image="bun-app") as sbx:    print(sbx.exec(["bun", "--version"]).stdout)

Recipe commands run as root in /workspace. Building an image is free. A stored image is charged by its size.

Drive sandboxes from Bun

The withruntime package supports Bun as well as Node 22.12 or later. await using works on Bun. A Bun service can therefore create, run and delete sandboxes with the samples above, unchanged (JavaScript SDK).

Terminalbun add withruntime

A new account gets 100 free hours of a 1 GB machine in its first 30 days, with no card required:

Terminalnpx withruntime sandboxes run -- bun --version

Sources

Facts on this page were checked on 26 October 2026.

100 free hoursin your first 30 days.

of a 1 GB machine

  • No credit card
  • Four sandboxes at once, 2 vCPU and 4 GiB each
  • Then prepaid credit from $10, no plan fee
Start free, no card
Start free, no card