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. You can try it in your browser on the Playground: type Wax, see the WAT and diagnostics live, with no install.

Installation

npm

The easiest way to get wax is from npm; it ships a single cross-platform WebAssembly build that runs on any Node 22+ (Linux, macOS, Windows):

npm install -g @wax-wasm/wax

Prebuilt binaries

Native wax executables for Linux, macOS (Apple silicon and Intel), and Windows (with SHA256SUMS) are attached to each release. Download the one for your platform, make it executable, and put it on your PATH:

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

The edge prerelease carries the same binaries built from the latest main, rebuilt on every push.

opam

wax is published on the opam repository, so if you have an OCaml toolchain it builds and installs with:

opam install 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

Wax works in Visual Studio Code through a dedicated extension, and in any editor with a Language Server Protocol client (Neovim, Emacs, Helix, and others) through the built-in wax lsp server paired with the tree-sitter-wax grammar. Both give the same features: diagnostics, hover, go to definition, find references, rename, completion, signature help, formatting, and more. See Editor Support for the details and per-editor setup.

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