Skip to content

WebAssembly with Elide

Run WASI command modules with Elide, map host directories, load WebAssembly libraries from JavaScript and TypeScript, and check supported proposals.

On this page

WebAssembly support is experimental in 1.6.0.

You haveUseResult
A WASI commandelide run app.wasmRuns the module with WASI Preview 1 imports.
A WASM libraryThe WebAssembly API or an ES module import from JS/TSExposes the module’s exports.
0:11 / 0:11

To compile Java or Kotlin to WebAssembly, see WebImage; its output needs its JavaScript loader, not elide run. Target guides: Browser WASM and Edge WASM.

Run a WASM file

elide run app.wasm
elide app.wasm
elide run app.wasm -- first second   # program arguments
elide run --timeout=5s app.wasm      # exit 124 after 5 seconds

Elide calls the exported _start, or _main if _start is absent. Load a module with neither from JavaScript.

BehaviorValue
Argument zeroThe module’s absolute path.
Exit statusSet by WASI proc_exit, not by a function’s return value.
Traps, malformed binariesNonzero exit.
--timeoutCovers instantiation and execution; exits 124.

Project entrypoints

Set the module as the entrypoint in elide.pkl, then run elide run:

amends "elide:project.pkl"
name = "wasm-app"
entrypoint { "app.wasm" }

See Project setup.

WASI

Commands get WASI Preview 1 imports under wasi_snapshot_preview1: standard streams, arguments, exit status, and filesystem operations. Libraries loaded from JavaScript do not get WASI.

Directory access

WASI commands see no host directories until you map one:

elide -Xpolyglot.wasm.WasiMapDirs=work::./data run app.wasm

This maps ./data to the guest directory work. Separate mappings with commas: work::./data,output::./results.

The sandbox still applies. WASI file opens need read and write permission, even for reads:

elide -Xpolyglot.wasm.WasiMapDirs=work::./data run \
  --sandbox --allow-read=./data --allow-write=./data app.wasm

See Sandbox and Limits.

JavaScript and TypeScript interop

The global WebAssembly API needs no flag:

import { readFile } from "node:fs/promises";

const bytes = await readFile(new URL("./math.wasm", import.meta.url));
const { instance } = await WebAssembly.instantiate(bytes, {});
console.log(instance.exports.add(20, 22));

Modules loaded from JavaScript do not run _start or _main. The second argument supplies the module’s imports:

const imports = { env: { log: (value) => console.log(value) } };
const { instance } = await WebAssembly.instantiate(bytes, imports);

The API includes validate, compile, Module, Instance, Memory, Table, Global, and import and export inspection. A compiled Module can be instantiated more than once. File reads follow the usual permissions.

ES module imports

import { add } from "./math.wasm";
console.log(add(20, 22));
const math = await import("./math.wasm");
console.log(math.add(20, 22));

Specifiers can be paths, file: URLs, or package exports that resolve to .wasm. A source-phase import returns the compiled module to instantiate yourself:

import source mathModule from "./math.wasm";
const math = await WebAssembly.instantiate(mathModule, {});
console.log(math.exports.add(20, 22));

Supported WebAssembly proposals

On by default, for commands and JS/TS interop:

  • Mutable globals and sign-extension operators
  • Non-trapping float-to-integer conversions
  • Multi-value function and block results
  • Bulk memory operations and reference types
  • Multiple memories
  • Extended constant expressions
  • Exception handling
  • Typed function references
  • Garbage-collected types (WasmGC)
  • Tail calls
  • Fixed-width SIMD (v128) and relaxed SIMD, except with Python installed

Off by default:

ProposalOptionNotes
Memory64wasm.Memory64Also requires wasm.UseUnsafeMemory.
Threads and atomicswasm.ThreadsNo WASI thread-spawning host API is supplied.
Wide integer arithmeticwasm.WideArithmeticSeparate from ordinary i64 arithmetic.
Legacy exception handlingwasm.LegacyExceptionsThe newer exception-handling proposal is on by default.

Enable one with -Xpolyglot.<option>=true, for example -Xpolyglot.wasm.WideArithmetic=true. This does not supply the host imports a module needs.

Limits

  • Binary modules only. No .wat, no compiling C or Rust, no WASM REPL.
  • WASI Preview 1 only. No WASI Preview 2, component model, or node:wasi; no general network access.
  • Host imports. elide run supplies only WASI, not browser APIs or Emscripten glue.
  • SIMD with Python. With Python installed, SIMD modules are rejected. Use an install without Python or a scalar build of the module.

Samples

Was this page helpful?