How to run TypeScript code in a sandbox
Write the .ts file into an isolated microVM and run it with Node.js type stripping or Bun, both already installed, with no build step.
On Runtime there is nothing to install: Node.js 24.21.0 and Bun 1.4.0 are in
every sandbox, and both run a .ts file directly. Each sandbox is a
Firecracker microVM with its own kernel, started in 351 ms at the median on
24 September 2026 (speed), so a coding agent can test each
TypeScript snippet it writes in a fresh machine. The code interpreter adds a
stateful TypeScript session.
Three ways to run it
| Way | Command | Type checks? | Notes |
|---|---|---|---|
| Node.js type stripping | node job.ts |
No | Erasable syntax only; imports need the .ts extension |
| Bun | bun job.ts |
No | Transpiles every file on the fly, TSX included |
| Code interpreter | language: "typescript" |
No | Keeps variables between cells; in the default image |
| TypeScript compiler | npx tsc --noEmit |
Yes | Installs typescript from npm (7.0.2 on 25 September 2026) |
Node.js runs files that contain only erasable TypeScript syntax by default since v22.18.0 and v23.6.0, and the feature is marked stable from v24.12.0. It replaces types with whitespace and does no type checking. Enums, namespaces with runtime code, parameter properties, import aliases and decorators are refused (Node.js). Bun "transpiles every file on the fly with its native transpiler before running it" (Bun), so those forms work there.
Run a TypeScript file
TypeScriptimport { Sandbox } from "withruntime";const source = `type Point = { x: number; y: number };const dist = (a: Point, b: Point): number => Math.hypot(a.x - b.x, a.y - b.y);console.log(dist({ x: 0, y: 0 }, { x: 3, y: 4 }));`;await using sbx = await Sandbox.create({ network: { internet: false }, timeoutSeconds: 300, onLeaseEnd: "stop",});await sbx.files.write("/workspace/job.ts", source);const node = await sbx.exec(["node", "job.ts"], { timeoutMs: 20_000 });const bun = await sbx.exec(["bun", "job.ts"], { timeoutMs: 20_000 });console.log(node.stdout, bun.stdout); // 5 and 5Pythonfrom withruntime import Sandboxsource = """type Point = { x: number; y: number };const dist = (a: Point, b: Point): number => Math.hypot(a.x - b.x, a.y - b.y);console.log(dist({ x: 0, y: 0 }, { x: 3, y: 4 }));"""with Sandbox.create(network={"internet": False}, timeout_seconds=300, on_lease_end="stop") as sbx: sbx.files.write("/workspace/job.ts", source) node = sbx.exec(["node", "job.ts"], timeout_ms=20_000) bun = sbx.exec(["bun", "job.ts"], timeout_ms=20_000) print(node.stdout, bun.stdout) # 5 and 5Pass the file to the runtime as an array. No shell parses the path or the arguments.
Type-check what a model wrote
Running TypeScript skips the types. To reject code that does not type-check, install the compiler once, then close the network and check each answer:
TypeScriptimport { Sandbox } from "withruntime";await using sbx = await Sandbox.create({ network: { internet: true, allow: ["registry.npmjs.org"] }, timeoutSeconds: 900, onLeaseEnd: "stop",});await sbx.exec("npm init -y && npm install --no-fund --no-audit typescript", { check: true, timeoutMs: 180_000,});await sbx.network.set({ internet: false });await sbx.files.write("/workspace/answer.ts", "const n: number = 'seven';\nconsole.log(n);");const tsc = await sbx.exec(["npx", "tsc", "--noEmit", "--strict", "answer.ts"], { timeoutMs: 60_000,});if (tsc.exitCode !== 0) console.log("type errors:\n" + tsc.stdout + tsc.stderr);else console.log((await sbx.exec(["node", "answer.ts"], { timeoutMs: 20_000 })).stdout);Pythonfrom withruntime import Sandboxwith Sandbox.create( network={"internet": True, "allow": ["registry.npmjs.org"]}, timeout_seconds=900, on_lease_end="stop",) as sbx: sbx.exec("npm init -y && npm install --no-fund --no-audit typescript", check=True, timeout_ms=180_000) sbx.network.set(internet=False) sbx.files.write("/workspace/answer.ts", "const n: number = 'seven';\nconsole.log(n);") tsc = sbx.exec(["npx", "tsc", "--noEmit", "--strict", "answer.ts"], timeout_ms=60_000) if tsc.exit_code != 0: print("type errors:\n" + tsc.stdout + tsc.stderr) else: print(sbx.exec(["node", "answer.ts"], timeout_ms=20_000).stdout)Send the compiler's errors back to the model as they are, and run the code only once it type-checks.
A TypeScript notebook
TypeScriptimport { Sandbox } from "withruntime";await using sbx = await Sandbox.create({ network: { internet: false } });await sbx.interpreter.run("const prices: number[] = [3.5, 2.25, 4]", { language: "typescript" });const cell = await sbx.interpreter.run("prices.reduce((a, b) => a + b, 0)", { language: "typescript",});console.log(cell.results[0]?.data["text/plain"]); // 9.75Pythonfrom withruntime import Sandboxwith Sandbox.create(network={"internet": False}) as sbx: sbx.interpreter.run("const prices: number[] = [3.5, 2.25, 4]", language="typescript") cell = sbx.interpreter.run("prices.reduce((a, b) => a + b, 0)", language="typescript") print(cell["results"][0]["data"]["text/plain"]) # 9.75TypeScript is in the default image, so the first cell starts without an install (code interpreter).
A project with a tsconfig.json
Upload the project, install its dependencies and run its own scripts. Build an image with the compiler and your usual tools once, so each sandbox skips the install:
TypeScriptimport { Runtime } from "withruntime";const runtime = new Runtime();await runtime.images.build({ name: "ts", recipe: { npm: ["typescript", "tsx"] } });await using sbx = await runtime.sandboxes.create({ image: "ts", timeoutSeconds: 1800 });await sbx.files.upload("./my-project", "/workspace/app");await sbx.exec("cd app && npm ci && npx tsc --noEmit && npm test", { check: true, timeoutMs: 900_000, onStdout: (text) => process.stdout.write(text),});Pythonimport sysfrom withruntime import Runtimeruntime = Runtime()runtime.images.build(name="ts", recipe={"npm": ["typescript", "tsx"]})with runtime.sandboxes.create(image="ts", timeout_seconds=1800) as sbx: sbx.files.upload("./my-project", "/workspace/app") sbx.exec("cd app && npm ci && npx tsc --noEmit && npm test", check=True, timeout_ms=900_000, on_stdout=sys.stdout.write)The host side is TypeScript too: withruntime runs on Node 22 or later and
Bun, and await using stops the sandbox when the block ends
(JavaScript SDK).
Related
- Run JavaScript and Node.js code in a sandbox
- Run Bun in a sandbox
- Run Deno code in a sandbox
- A coding agent's sandbox
- What is a code interpreter?
Terminalnpx withruntime sandbox run --trial -- bun --versionNew accounts get 50 free sandbox hours, no card.
Sources
- Node.js, TypeScript type stripping: https://nodejs.org/api/typescript.html (read 25 September 2026)
- Bun runtime: https://bun.com/docs/runtime (read 25 September 2026)
- npm registry,
typescriptlatest version 7.0.2: https://registry.npmjs.org/typescript/latest (read 25 September 2026)
Facts on this page were checked on 25 September 2026.