RuntimeRegistry.
Runtime summary
| Runtime | Image | Extension | Inline code (-e) | Command (inline) | Command (file) |
|---|---|---|---|---|---|
| Python | isol8:python | .py | Yes | python3 -c <code> | python3 <path> |
| Node.js | isol8:node | .js | Yes | node -e <code> | node <path> |
| Bun | isol8:bun | .ts | Yes | bun -e <code> | bun run <path> |
| Deno | isol8:deno | .mts | No | Throws error | deno run --allow-read=/sandbox,/tmp --allow-write=/sandbox,/tmp --allow-env --allow-net <path> |
| Bash | isol8:bash | .sh | Yes | bash -c <code> | bash <path> |
Auto-detection
When you run a file through the CLI (isol8 run script.py), isol8 auto-detects the runtime from the file extension using RuntimeRegistry.detect(). The mapping is:
| Extension | Runtime |
|---|---|
.py | Python |
.js | Node.js |
.ts | Bun |
.mts | Deno |
.sh | Bash |
.ts files default to Bun, not Deno. This is because Bun is registered after Node in the registry and wins the .ts extension. To run TypeScript with Deno, either:
- Use the
.mtsextension, or - Pass
--runtime denoexplicitly
Registration order
Adapters are registered in this order:- Python (
.py) - Node.js (
.js) - Bun (
.ts) — wins the.tsextension - Bash (
.sh) - Deno (
.mts) — uses.mtsto avoid collision
.ts before Deno registers .mts, there is no collision and both coexist.
Python
Image:isol8:python (built from alpine:3.21 base stage)
Installed packages: python3, py3-pip
Execution modes:
pip install via the installPackages option in ExecutionRequest. isol8 runs pip install <packages> before executing your code.
Dockerfile stage:
base stage, which provides:
- Alpine 3.21
tinias PID 1 (proper signal handling)curlandca-certificates- The HTTP/HTTPS filtering proxy at
/usr/local/bin/proxy.mjs - Working directory set to
/sandbox
Node.js
Image:isol8:node (built from alpine:3.21 base stage)
Installed packages: nodejs, npm
Execution modes:
npm install via the installPackages option. isol8 runs npm install <packages> inside the container before executing your code.
Dockerfile stage:
base stage (same as Python).
Bun
Image:isol8:bun (built from alpine:3.21 base stage)
Installed packages: bash, unzip, libstdc++, libgcc, plus Bun installed from bun.sh/install
Execution modes:
.ts — Bun is the default runtime for TypeScript files. It has first-class TypeScript support with no compilation step.
Package installation: Use bun add via the installPackages option. isol8 runs bun add <packages> inside the container before executing your code.
Dockerfile stage:
base stage. The install script downloads and extracts Bun, then the binary is moved to /usr/local/bin so it is on the system PATH.
Deno
Image:isol8:deno (built from denoland/deno:alpine — not the shared base stage)
Execution modes:
.mts — chosen to avoid collision with Bun’s .ts. The .mts extension signals “module TypeScript” and is natively understood by Deno.
Permissions: Deno runs with the following explicit permission flags:
| Flag | Scope | Purpose |
|---|---|---|
--allow-read | /sandbox, /tmp | Read files in the sandbox working directory and temp |
--allow-write | /sandbox, /tmp | Write files in the sandbox working directory and temp |
--allow-env | All | Access environment variables (needed for user-provided env) |
--allow-net | All | Network access (actual connectivity depends on container’s network mode) |
--allow-net grants Deno permission to make network calls, but the container’s network mode (none, bridge, or filtered) determines whether those calls actually succeed. With network: "none", the container has no network interface regardless of Deno’s permission flags.
Dockerfile stage:
base stage. It uses denoland/deno:alpine directly and re-installs tini, curl, ca-certificates, and the proxy script. This is because the official Deno Alpine image includes a pre-built Deno binary that is easier to use than building from source.
Bash
Image:isol8:bash (built from alpine:3.21 base stage)
Installed packages: bash
Execution modes:
installPackages. Use apk add within your bash script if you need additional system packages (requires appropriate container permissions).
Dockerfile stage:
base stage. Alpine uses ash by default, so bash must be explicitly installed.
Persistent containers and runtime locking
When using persistent sessions (mode: "persistent"), the container is created with a specific runtime’s Docker image. Once created, the container cannot switch runtimes. Attempting to execute code with a different runtime on an existing persistent container throws:
Runtime adapter interface
Every runtime adapter implements this interface:Custom runtime adapters
You can register custom runtime adapters when using isol8 as a library:isol8:ruby) using the same base stage pattern from the Dockerfile.
Base image architecture
All runtime images (except Deno) share a common base stage: The base stage provides:| Component | Purpose |
|---|---|
tini | PID 1 init process for proper signal forwarding and zombie reaping |
curl | Used for health checks and package downloads |
ca-certificates | TLS certificate bundle for HTTPS requests |
proxy.mjs | HTTP/HTTPS filtering proxy for network: "filtered" mode |
/sandbox | Working directory for all code execution |