WebAssembly Import/Export Reference

Wasm import and export descriptor types — func, table, memory, global — with syntax.

Reference for WebAssembly module import and export descriptor kinds — func, table, memory, global — with WAT syntax and the JavaScript instantiate API binding. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What are the four WebAssembly external kinds?

A module can import and export functions (func), tables (table), linear memories (memory) and globals (global). Each import names a two-level module/name pair, and each export names a single field. These are the only externally-visible entity kinds.

WebAssembly module boundaries

A WebAssembly module communicates with its host through two flat lists: imports it requires and exports it offers. Both reference one of four external kinds — func, table, memory or global. This reference shows the WebAssembly text (WAT) syntax for each and the matching JavaScript binding used by WebAssembly.instantiate.

How it works

Every import carries a two-level name: a module string and a field string. At instantiation the host supplies an import object — a nested record — and the linker matches (import "mod" "name" ...) to importObject.mod.name:

(module
  (import "env" "log" (func $log (param i32)))
  (import "env" "mem" (memory 1))
  (global $g (export "counter") (mut i32) (i32.const 0))
  (func (export "run") ... ))
const importObject = {
  env: {
    log: (n) => console.log(n),
    mem: new WebAssembly.Memory({ initial: 1 }),
  },
};
const { instance } = await WebAssembly.instantiate(bytes, importObject);
instance.exports.run();

Exports appear on instance.exports after instantiation. The supplied import value must match the declared kind and limits, or a LinkError is thrown.

Each external kind in detail

func imports and exports

A function import names the expected type signature. The JavaScript side provides a plain function — any JS callable works. At the Wasm boundary, types are coerced: an i32 parameter becomes a 32-bit integer (truncated if needed), an f64 becomes a double, and an i64 becomes a BigInt. If the supplied function returns a value, Wasm ignores any types it does not expect.

(import "env" "log" (func $log (param i32) (result)))

A function export is simply named. In JavaScript, instance.exports.log is a regular callable function that runs Wasm when called.

memory imports and exports

A module can declare at most one linear memory (in the current standard). The size is declared in 64 KiB pages. When importing, the supplied WebAssembly.Memory must already meet the declared minimum; when exporting, instance.exports.mem exposes the underlying memory object so the host can read and write raw bytes via ArrayBuffer.

(import "env" "mem" (memory 1 10))
;; minimum 1 page (64 KiB), maximum 10 pages (640 KiB)

Sharing a memory import is the standard way for Wasm and its host to exchange large data without serialization.

table imports and exports

A WebAssembly table is a typed array of references — currently funcref or externref. Tables power call_indirect, the Wasm equivalent of a function pointer dispatch. An imported table, like an imported memory, must satisfy the declared minimum size.

(import "env" "tbl" (table 4 funcref))

The JavaScript WebAssembly.Table API lets you read and write table slots from the host, enabling dynamic function registration patterns.

global imports and exports

Globals are scalar values (i32, i64, f32, f64) that can be shared between the host and the module. An immutable global can be supplied as a plain number (or BigInt for i64). A mutable global must be a WebAssembly.Global constructed with { value: 'i32', mutable: true }.

(import "env" "base" (global $base (mut i32)))

Exporting a mutable global lets the host observe changes the Wasm code makes to it without reading memory.

Tips and notes

  • Memory size is in 64 KiB pages; a (memory 1) is exactly 65536 bytes.
  • i64 globals and params surface in JS as BigInt, not Number. Pass BigInt literals or BigInt(n).
  • Mutable globals need new WebAssembly.Global({ value: 'i32', mutable: true }, initialValue).
  • A table’s element type is funcref (or externref with the reference-types proposal enabled).
  • A missing import or wrong type at instantiation throws a LinkError synchronously — check the import object shape and types before blaming Wasm logic.
  • Use WebAssembly.instantiateStreaming for production (parses the binary as it downloads) and WebAssembly.instantiate with a pre-fetched buffer in tests or environments without streaming support.