Skip to content

Modules and Functions

Every piece of WebAssembly code lives inside a module. The module is the top-level unit of compilation and deployment — it is what you compile, transfer over the network, and instantiate in the browser. Inside a module you define functions, declare memory, import from JavaScript, and choose what to export.

The outermost s-expression in every WAT file is (module ...). Everything else is nested inside it:

(module
;; functions, imports, exports, memory, globals go here
)

A module with no contents is valid WAT and compiles to a tiny .wasm file — it just has nothing useful in it yet.

Functions are declared with (func ...). A function that takes no arguments and returns nothing looks like this:

(module
(func
;; empty body — does nothing
)
)

To accept arguments you add (param <name> <type>) attributes. To declare a return type you add (result <type>). Parameter names start with $ and are optional but strongly recommended for readability:

(module
(func (param $x i32) (param $y i32) (result i32)
local.get $x
local.get $y
i32.mul)
)

This module compiles fine, but the function is completely unreachable from JavaScript because it has not been exported.

JavaScript can only call functions the module explicitly exports. There are two equivalent syntaxes.

Separate export statement — define the function with a name, then export it:

(module
(func $multiply (param $x i32) (param $y i32) (result i32)
local.get $x
local.get $y
i32.mul)
(export "multiply" (func $multiply))
)

Inline export — attach the export directly to the func declaration:

(module
(func (export "multiply") (param $x i32) (param $y i32) (result i32)
local.get $x
local.get $y
i32.mul)
)

Both forms produce identical .wasm bytes. The inline style is more concise; the separate-statement style is useful when you want to export the same function under multiple names or keep declarations and exports visually separated.

The example below defines a multiply function using the inline export syntax and calls it from JavaScript.

WebAssembly
Which syntax exports a function from a WAT module?
Can JavaScript call a function that is defined but not exported?
What is the outermost s-expression in every WAT file?