Skip to main content
wasi_snapshot_preview1 for WebAssembly modules, shaped like Node’s node:wasi. WebAssembly itself is the standard global (MDN).
Nothing is patched globally. Create a WASI, pass its imports to WebAssembly.instantiate, then start() a command or initialize() a reactor.

WASI

constructor


Creates one WASI environment. A host directory outside data/ needs the filesystem permission and must exist.

getImportObject


The imports to pass to WebAssembly.instantiate. wasi.wasiImport is the same syscall table on its own, for merging with your own imports.

start


Runs a command: calls _start() and returns the exit code (0 when _start returns). Call start() or initialize() once per WASI.
With returnOnExit: false, proc_exit throws an Error with exitCode.

initialize


Sets up a reactor (a module without _start): calls _initialize() if it’s exported. Then call its exports yourself.

dispose


Closes every file the guest opened. Happens on unload anyway. alive is false afterwards, and using disposes at the end of the block.

Guest environment

Symlinks and junctions inside a preopen work as long as they stay inside it; one that leads out is ENOTCAPABLE, like ... File access is direct: opening, reading and stat-ing thousands of files costs about what it costs natively, and the disk time doesn’t count against the script’s limits.

Long-running modules

A wasm module that runs for seconds at a time (an emulator, an engine, a big parse) would hold up every script on the shared thread, and the host stops calls that run too long. Three ways out:
  • Run it in a Worker. @native/wasi and @native/fs work there, there’s no time limit, and a WebAssembly.Module you post is shared already compiled.
  • Compile asynchronously. await WebAssembly.compile(bytes) / WebAssembly.instantiate(bytes) compile on background threads and don’t block anybody. Big modules start on the fast baseline compiler and get optimized in the background while they run.
  • Yield with JSPI. Wrap an async import in WebAssembly.Suspending and the export in WebAssembly.promising. The module can then pause on a promise in the middle of a call and resume in a later tick. It’s an experimental V8 feature (TypeScript doesn’t declare it yet, cast through any).

Example

Run a WASI command from data/app.wasm.