# 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](/docs/pricing)). ## Run a Bun script ```ts import { 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); ``` ```python from withruntime import Sandbox 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); """ 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](https://bun.com/docs/runtime)). Bun does not type-check. For `tsc`, see [TypeScript in a sandbox](/languages/typescript). ## 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](/docs/sandbox-environment#who-you-are)). ## 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](https://bun.com/docs/test)). ```ts check import { 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 network const 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; ``` ```python check import sys from withruntime import Sandbox with 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](/docs/javascript#share-a-port). ```ts check import { 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"`, and it needs `unzip` ([Bun installation](https://bun.com/docs/installation)). To pin one release for every sandbox, run the installer in a [custom image](/docs/images) recipe. Set `BUN_INSTALL` to `/usr/local`, so `bun` lands on the sandbox user's `PATH`: ```ts check import { 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); ``` ```python check from withruntime import Runtime runtime = 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](/docs/javascript)). ```bash no-run bun add withruntime ``` ## Related - [Run TypeScript code in a sandbox](/languages/typescript) - [Run JavaScript and Node.js code in a sandbox](/languages/javascript) - [Preview apps an agent built](/use-cases/preview-agent-built-apps) - [Run agent evals and SWE-bench](/use-cases/agent-evals-and-swe-bench) A new account gets 100 free hours of a 1 GB machine in its first 30 days, with no card required: ```bash no-run npx withruntime sandboxes run -- bun --version ``` ## Sources - Bun runtime: https://bun.com/docs/runtime (read 26 October 2026) - Bun test runner: https://bun.com/docs/test (read 26 October 2026) - Bun installation: https://bun.com/docs/installation (read 26 October 2026) - `bun add`: https://bun.com/docs/cli/add (read 26 October 2026) Facts on this page were checked on 26 October 2026.