Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

Wax is a Rust-like syntax for WebAssembly that compiles to standard Wasm binary or text formats. It provides a more familiar programming experience while maintaining a direct correspondence to WebAssembly concepts. It is validated against the official WebAssembly spec test suite and a differential, round-trip fuzzing harness, so conversions preserve meaning across all three formats. See Feature Support for the proposals it covers.

Why Wax?

WebAssembly Text format (WAT) uses S-expressions and stack-based operations, which can be verbose and unfamiliar to most programmers:

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

Wax provides an expression-oriented syntax that feels more natural:

fn add(x: i32, y: i32) -> i32 {
    x + y;
}

Both compile to identical WebAssembly bytecode.

Installation

Prebuilt binaries

Native wax executables for Linux, macOS (Apple silicon and Intel), and Windows (with SHA256SUMS) are attached to the edge prerelease, which is rebuilt on every push to main. Download the one for your platform, make it executable, and put it on your PATH:

curl -LO https://github.com/ocsigen/wax/releases/download/edge/wax-linux-x86_64
chmod +x wax-linux-x86_64 && mv wax-linux-x86_64 /usr/local/bin/wax

From source

Requirements: Opam (2.1+) and OCaml 4.14+ (5.0+ to run the full test suite).

# Install dependencies
opam install . --deps-only

# Build
dune build

# Install globally
opam install .

Editor support

A Wax extension for Visual Studio Code supports both .wax and WebAssembly text (.wat) files: syntax highlighting, formatting (with format on save), diagnostics as you type, a document outline, snippets, and commands to preview the compiled WAT or decompiled Wax side by side. It runs the toolchain compiled to WebAssembly in-process, so it works the same in desktop and web VS Code (including vscode.dev).

Quick Start

Create a file hello.wax:

#[export = "add"]
fn add(x: i32, y: i32) -> i32 {
    x + y;
}

#[export = "factorial"]
fn factorial(n: i32) -> i32 {
    if n <=s 1 => i32 {
        1;
    } else {
        n * factorial(n - 1);
    }
}

Compile to WebAssembly binary:

wax hello.wax -o hello.wasm

Or convert to WebAssembly text format to see the generated WAT:

wax hello.wax -f wat

Reformat files in place with the format command:

wax format -i hello.wax

Supported Conversions

Wax supports all 9 combinations of input and output formats:

InputOutputUse Case
.wax.wasmCompile to binary
.wax.watCompile to text
.wax.waxFormat / type-check
.wat.wasmAssemble to binary
.wat.waxDecompile to Wax
.wat.watFormat
.wasm.watDisassemble
.wasm.waxDecompile to Wax
.wasm.wasmRound-trip

Type Checking

Compiling Wax to .wat or .wasm type-checks it automatically; type errors are reported before any output is produced. For example, adding an i32 and an f64:

Error: This operator cannot be applied to operands of types i32 and f64.
 ──➤  hello.wax:3:7
1 │ #[export = "add"]
2 │ fn add(x: i32, y: f64) -> i32 {
3 │     x + y;
  ·       ^
4 │ }

The -v/--validate flag adds checks that are off by default: it validates a same-format conversion (.wax.wax) or a trusted .wasm input, and reports unused locals.

Next Steps