userland.rundocs70Try the demo
Introduction

NanoVM documentation

NanoVM runs real programs inside a browser tab with no server: BusyBox and Node.js as RISC-V Linux binaries, Node.js on the browser's own JS engine, wasm32-wasip1 command-line tools, and sandboxed JavaScript. One kernel routes each program to the right runner, and every runner shares one virtual filesystem.

Most people use NanoVM through the TypeScript SDK, @userland-run/nano-sdk: it boots the VM, gives you a filesystem and a process API, and adds a shell engine, an HTTP preview bridge, a JavaScript sandbox, a Web Worker transport, a signed app catalog and an embeddable terminal. Every code block with a Run button on these pages executes for real in your tab. Nothing is downloaded until you press it.

SDK · JavaScript

Your first run

nano is a booted instance (createNano() with the BusyBox image). shExec() runs a full shell line on the emulated RISC-V CPU; node() runs a Node.js program on the browser's JS engine. Both see the same files.

javascript
nano.fs.writeFile("/work/hello.txt", "hello from the VFS\n");
const sh = await nano.shExec("cat /work/hello.txt; uname -m");
print(sh.stdout.trim());
const js = await nano.node(["-e", "console.log(require('fs').readFileSync('/work/hello.txt', 'utf8').trim(), '(node', process.version + ')')"]);
print(js.stdout.trim());
loading…
Expected output
hello from the VFS
riscv64
hello from the VFS (node v25.4.0)

The four runners

NanoVM is a shared kernel (bus, virtual filesystem, process router, networking, capabilities, services) plus peer runners. A runner imports only from the kernel, never from another runner; cross-runner work goes through the router and the shared VFS. See Architecture for the details.

Runner
What it runs
Engine
Reach it with
riscv
RV64GC Linux ELF binaries: BusyBox, the Node.js v25.4.0 ELF, catalog apps such as ripgrep
emulated CPU (Rust compiled to WebAssembly)
run, exec, shExec, node() with engines.node: "vm"
node
Node.js programs on the browser's own JS engine ("nodert")
host JS engine
node() with engines.node: "host" or "auto"
wasm
wasm32-wasip1 command-line apps
host WebAssembly engine
registerWasmApp + execWasmApp
boa
untrusted JavaScript with no ambient authority
Boa interpreter (Rust compiled to WebAssembly)
script() / scripting()

The RISC-V runner is the fidelity reference: it runs unmodified upstream binaries instruction by instruction, so it is the slowest. The host-engine Node runner is fast but reimplements Node's built-in modules; its known differences are listed in Limitations. Pick per program with engines.

What you can build

Where to go next

NanoVM is a userland VM: it runs Linux programs against a syscall layer, not a kernel with device drivers. It cannot boot an operating system image. For that you want a full-system emulator; see the comparisons.