SDK overview
@userland-run/nano-sdk embeds NanoVM in any web app: write files, run real binaries, stream output, host servers and sandbox plugins — from a typed, ESM, zero-dependency package.
The SDK is a thin, fully-typed layer over NanoVM's runners. It boots the platform, gives you a filesystem and a process API, and layers higher-level modes on top — a shell engine, an HTTP serve bridge, a sandboxed Boa scripting engine, a Web Worker transport, and the app catalog. installApp pulls tools on demand, including kind:"wasm-app" commands that run on the wasm runner (registerWasmApp / execWasmApp).
Install
npm install @userland-run/nano-sdk
ESM-only, ships complete TypeScript types, and has zero runtime dependencies — the RISC-V VM, the Boa scripting engine, and the node/wasm runner tiers are vendored into the bundle.
Cross-origin isolation
NanoVM allocates a shared WebAssembly.Memory, which requires the page to be cross-origin isolated. Either set the response headers yourself, or register the bundled service worker (exported at @userland-run/nano-sdk/service-worker as nano-sw.js), which injects them for you.
Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp
Boot the VM
import { createNano } from "@userland-run/nano-sdk";
// console.wasm bundles a BusyBox shell + coreutils; the slim nano.wasm bundles
// nothing — guest programs install on demand with nano.installApp("node").
const nano = await createNano({ image: { wasm: "/nano/console.wasm" } });
nano.fs.writeFile("/app/data.txt", "1\n2\n3\n");
const { stdout } = await nano.shExec("sort -rn /app/data.txt | head -1");
console.log(stdout); // "3"The image config is just { wasm } pointing at a build (URL or raw bytes). For the slim default build, install guest programs from the catalog at runtime — await nano.installApp("node"). If you would rather self-host the binaries and bundle them at boot, the nanoImage({ baseUrl, withBusybox, withNode, withDevenv }) helper builds that config for you.
The five modes
- Code mode — write files, run commands, read results.
- Terminal mode — a stateful shell engine (cwd / env, sh semantics) for any renderer.
- Serve mode — bridge an in-VM HTTP server to a preview iframe via a service worker.
- Scripting mode — a sandboxed, capability-scoped Boa JavaScript engine.
- Worker transport — host the VM in a Web Worker so the UI thread stays responsive.