Runtimes: WASM, Firecracker, Docker
Every Tabbify app runs as a detached runner process hosted by a supervisor. What that runner does inside — execute a WASM component, boot a microVM, or run a container — is the runtime, and you pick it per deploy target.
Three runtimes
wasm-http— your code as a WASI-HTTP component, executed in-process by wasmtime. Lightest and fastest to start; runs everywhere, no host privileges needed.firecracker— a microVM with its own kernel and ext4 rootfs, built from your OCI image. Strong isolation; needs Linux with/dev/kvm.docker— a plain container via the host Docker daemon. The most familiar path; runs anywhere Docker does.
A key design point: runtime is chosen at deploy time, not baked at build time. The same Docker image can run as a container on one supervisor and a Firecracker microVM on another. Your [build].kind (docker or wasm) decides the artifact; the runtime decides how it executes.
Choosing one
| Want | Use |
|---|---|
| Smallest cold start, runs anywhere | wasm-http |
| Container isolation, fast iteration | docker |
| VM-grade isolation for untrusted code | firecracker |
WASM cold-starts in under a second; Firecracker boots in roughly two. Both wasm-http and docker run on any host. Firecracker only runs on a Linux supervisor with KVM — on macOS or a nested VM without /dev/kvm, it fails by design.
Set it in tabbify.toml
Pick a default in [runtime], then override per target in each [[deploy]] block. See the tabbify.toml manifest for the full schema.
[runtime]
type = "docker" # docker | firecracker | wasm-http
lifecycle = "on_request" # always_on | on_request
idle_timeout_sec = 300
memory_mb = 512
[[deploy]]
supervisor = "ec2-prod"
runtime = "docker"
[[deploy]]
supervisor = "thinkpad"
runtime = "firecracker" # same image, VM isolation here
Capability detection
A supervisor only advertises what it can actually run. It always offers wasm-http; it adds docker if the daemon answers and firecracker if /dev/kvm is readable. These show up as mesh tags, and the node refuses to place an app on a supervisor that lacks the requested runtime:
curl -H 'Authorization: Bearer <KEY>' http://3.124.69.92:8090/v1/supervisors
# [{"display_name":"ec2-prod","tags":["supervisor","docker"]},
# {"display_name":"thinkpad","tags":["supervisor","firecracker","wasm-http"]}]
All three runtimes are implemented and proven in production runners: WASM and Docker are mature, and Firecracker has been verified live on Linux hosts with real KVM. Whichever you pick, the app lands on a stable private mesh address and the runner contract — health, restart, lifecycle — stays the same.