userland.run70Try the demo
Compare · container2wasm

userland.run vs container2wasm

container2wasm converts a container image into a WebAssembly module: a CPU emulator boots a real Linux kernel, which starts the container. It is the closest relative of userland.run — both emulate a CPU to run unmodified binaries — but they emulate at different levels and target different jobs.

Last verified: · sources cited below

The short answer

  • Choose container2wasm to run an existing container image (x86_64, riscv64 or AArch64) in the browser or a WASI runtime with minimal porting — a full Linux kernel, runc and all.
  • Choose userland.run to build an app around in-browser execution: an SDK, a terminal component, in-tab dev-server previews, a signed app catalog, and fast non-emulated tiers for Node, wasm apps and sandboxed JS.

Side by side

container2wasmuserland.run
LicenseApache-2.0 for the converter; generated images include third-party software under their own licenses (Bochs, TinyEMU, QEMU, Linux, …). [1]Runtime: AGPL-3.0 or commercial UEL. SDK: MPL-2.0 or UEL. Source on GitHub.
How it worksFull-system emulation: Bochs (x86_64) or TinyEMU (RISC-V) boot Linux and run the container with runc; --to-js uses QEMU compiled to wasm with TCG JIT. [1]User-mode RV64GC RISC-V emulator + Linux syscall layer in wasm, plus peer runners: Node on the host JS engine, a wasm32-wasip1 runner, a Boa JS sandbox.
Node.jsWhatever Node build the container image contains, running under CPU emulation.Real Node.js v25.4.0 ELF on the emulator (fidelity), or nodert on the browser's JS engine (fast, with documented divergences).
Native binariesYes — arbitrary Linux binaries of the image's architecture; x86_64, riscv64 or AArch64 recommended. [1]Yes — static riscv64 Linux ELF binaries (BusyBox, ripgrep, …) and wasm32-wasip1 apps.
Offline / self-hostingStatic files plus wasm; the examples serve them from a plain web server. [1]Static files you host yourself. Catalog apps come from a signed CDN index (mirrorable via CdnOptions.baseUrl) and are cached in OPFS.
PricingNone (open source).Free under AGPL-3.0 / MPL-2.0. A commercial license (UEL) is available from And The Next GmbH for terms the open-source licenses don't provide.
BrowsersExample configs set COOP/COEP; the networking example is "tested only on Chrome". [1][2]Cross-origin isolation (COOP/COEP, or the shipped service worker) + SharedArrayBuffer. This site's sample suite runs in Chromium; other engines are not in the published test matrix.
NetworkingBrowser: HTTP(S) via a Fetch-based proxy (CORS applies) or packets over WebSocket to a host-side c2w-net. No built-in in-browser preview of servers. [1]Inbound: in-tab servers previewed via a service worker (/sw/<port>/). Outbound: HTTP through the host fetch (CORS applies; an optional self-hosted CORS proxy ships).
Status"This is an experimental software." Latest release v0.8.4 (2026-03-16). [1][3]Pre-1.0 and active — see the changelog.

Where container2wasm is better

  • Any image, any distro. A full kernel means glibc, dynamic linking, /proc, init systems and the long tail of Linux behaviour simply work.
  • x86_64. Most published containers are x86_64; userland.run only runs riscv64 binaries.
  • Outside the browser. The same module runs in WASI runtimes such as wasmtime.
  • JIT option. The QEMU-based --to-js path compiles guest code with TCG instead of interpreting each instruction.

Where userland.run is different

  • No kernel to boot. User-mode emulation implements the Linux syscall interface directly, so there is no boot and the slim core is 2.46 MB; binaries are fetched on demand.
  • Faster tiers when emulation isn't needed. Node on the host JS engine, wasm32-wasip1 apps on the browser's wasm engine and a Boa sandbox share the emulator's filesystem.
  • Built for embedding. A typed SDK, the <nano-terminal> component and in-tab dev-server previews.
  • Signed app catalog. Tools are installed per app with signature and hash verification instead of baked into one image.

The trade-off is coverage: userland.run implements the syscalls its workloads need (the reference lists 87), while container2wasm runs the real Linux kernel. If your workload is a whole distribution, container2wasm is the safer bet.

FAQ

Can userland.run run a Docker image?

No. It runs individual static riscv64 Linux executables and catalog apps on its own syscall layer; there is no container runtime or guest kernel. container2wasm is built for images.

Which one is faster?

Neither project publishes a head-to-head benchmark. User-mode emulation avoids booting and emulating a kernel; container2wasm's QEMU path can JIT guest code. Measure your own workload.

Do both need cross-origin isolation?

container2wasm's browser examples are served with COOP/COEP headers; userland.run requires cross-origin isolation too, either through headers or its shipped service worker.

Sources

  1. container2wasm on GitHub — READMEgithub.com/container2wasm/container2wasm
  2. container2wasm — examplesgithub.com/container2wasm/container2wasm/tree/main/examples
  3. container2wasm — releasesgithub.com/container2wasm/container2wasm/releases
  4. userland-run/nano — README and LICENSE.mdgithub.com/userland-run/nano
  5. userland-run/sdk — @userland-run/nano-sdk READMEgithub.com/userland-run/sdk

All third-party facts were checked against these pages on 2026-10-11. Products change — if something here is out of date, please open an issue.