Skip to main content
Ant runs WebAssembly modules natively through wasm-micro-runtime, exposed via the standard WebAssembly global. You can load a .wasm file, compile it, and call its exported functions — all from ordinary JavaScript with no native extensions required. WASI support is built in, which means you can run programs compiled from C, Rust, or Go as WebAssembly inside Ant.

Load and run a WASM module

The most common pattern is WebAssembly.instantiate(bytes, imports). You pass the raw bytes of a .wasm file and an optional imports object, and Ant returns a compiled instance whose exports you can call directly.
import { readFile } from 'ant:fs';

const [wasmFile, ...wasmArgs] = process.argv.slice(2);
if (!wasmFile) {
  console.error('Usage: ant wasm.mjs <file.wasm> [args...]');
  process.exit(1);
}

const bytes = await readFile(wasmFile);

const { instance } = await WebAssembly.instantiate(bytes, {
  wasi: { args: [wasmFile, ...wasmArgs] }
});

instance.exports._start();
This is the complete examples/wasm/index.mjs from the Ant repository. It reads a .wasm file from the command line, instantiates it with WASI enabled, and calls _start() — the conventional entry point for WASI programs. Run it with:
ant wasm.mjs program.wasm arg1 arg2
WASI enables WASM modules to access system capabilities — standard I/O, command-line arguments, and more — in a sandboxed, portable way. Pass { wasi: { args } } in the imports object to enable it.

WebAssembly API reference

Ant exposes the full standard WebAssembly global. The most useful entry points are below.

WebAssembly.instantiate

const { instance, module } = await WebAssembly.instantiate(bytes, imports);
Compiles and instantiates a WASM module in one step. bytes can be a Uint8Array, ArrayBuffer, or any typed array containing the raw .wasm binary. Returns a promise that resolves to an object with both the compiled module and a ready-to-call instance.

WebAssembly.compile

const module = await WebAssembly.compile(bytes);
Compiles bytes into a WebAssembly.Module without instantiating it. Use this when you want to compile once and instantiate multiple times with different import objects.

new WebAssembly.Instance

const instance = new WebAssembly.Instance(module, imports);
Synchronously instantiates an already-compiled WebAssembly.Module. This blocks the current thread and is suitable when you hold a pre-compiled module and want a quick, synchronous setup.

WebAssembly.validate

const valid = WebAssembly.validate(bytes);
Returns true if bytes is a valid WASM binary, false otherwise. Use this to check user-supplied files before attempting to compile or instantiate them.

Working with WASM exports

Once you have an instance, its exports object contains all the functions and memory the module exposes. The exact shape depends on the module.
WASI programs compiled from C, Rust, or Go typically export _start, which is equivalent to main().
import { readFile } from 'ant:fs';

const bytes = await readFile('program.wasm');
const { instance } = await WebAssembly.instantiate(bytes, {
  wasi: { args: ['program.wasm', '--flag'] }
});

instance.exports._start();

Minimal inline WASM

You can construct a WASM module from a Uint8Array without touching the filesystem. The bytes must form a valid WASM binary. Every WASM binary starts with the 4-byte magic \0asm followed by the 4-byte version 1. After that, sections describe types, functions, exports, and code.
// A minimal WASM module that exports an `add` function.
// Sections in order: magic, version, type, function, export, code.
const wasmBytes = new Uint8Array([
  0x00, 0x61, 0x73, 0x6d, // magic: \0asm
  0x01, 0x00, 0x00, 0x00, // version: 1
  0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, // type section: (i32, i32) -> i32
  0x03, 0x02, 0x01, 0x00, // function section: 1 function, type index 0
  0x07, 0x07, 0x01, 0x03, 0x61, 0x64, 0x64, 0x00, 0x00, // export section: "add" -> function 0
  0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b, // code section: local.get 0, local.get 1, i32.add
]);

const { instance } = await WebAssembly.instantiate(wasmBytes, {});
console.log(instance.exports.add(3, 4)); // 7
For most use cases you will compile .wasm files from a higher-level language rather than writing binary by hand. Use wat2wasm from the WABT toolkit to convert human-readable WAT text format to binary, or use the wasm-pack toolchain for Rust projects.

Validate before instantiating

If you accept WASM files from external sources, validate them before attempting to compile:
import { readFile } from 'ant:fs';

const bytes = await readFile(process.argv[2]);

if (!WebAssembly.validate(bytes)) {
  console.error('Invalid WASM binary');
  process.exit(1);
}

const { instance } = await WebAssembly.instantiate(bytes, {});
instance.exports._start();