watr
raw JSON → 4.5.0 verified Fri May 01 auth: no javascript
watr is a lightweight, zero-dependency WAT (WebAssembly Text format) compiler written in JavaScript. Current stable version is 4.5.0, with frequent releases adding support for upcoming WebAssembly proposals. It compiles WAT to binary (wasm), parses into AST, pretty-prints, minifies, optimizes, and polyfills newer features to MVP. Key differentiators: small bundle size (~84KB minified, ~24KB gzipped), high throughput (~4460 op/s vs 700-2200 for alternatives), spec-complete with GC, exception handling, and stack switching, built-in CLI, and a unique tagged template literal for instant wasm exports with JS interop.
Common errors
error Cannot find module 'watr' or its corresponding type declarations ↓
cause Using CommonJS require instead of ESM import.
fix
Use
import watr from 'watr' (ESM) or const watr = await import('watr') in Node with ESM enabled. If using TypeScript, ensure module resolution is 'node' or 'node16' and 'esModuleInterop' is true. error SyntaxError: Unexpected token ( ↓
cause Invalid WAT syntax; e.g., missing closing parenthesis or wrong instruction name.
fix
Use
parse(yourWat) to get detailed error with line/column. Check the WAT against the WebAssembly spec or use watr's print with formatting to debug. error TypeError: watr is not a function ↓
cause Trying to call the default export as a function instead of using it as a tagged template literal.
fix
Use watr
... (backticks) not watr('...'). For direct compilation, use the named compile import. error Error: Unknown type 'funcref' ↓
cause Older version of watr (<3.0.0) does not support reference types.
fix
Upgrade to watr >=3.0.0 (currently 4.5.0) which fully supports reference types and all proposals.
Warnings
breaking v4.0.0 removed several deprecated mnemonics and changed the compile API signature (removed old callback style). ↓
fix Update to use compile(source, options) which returns Uint8Array synchronously. If you used callbacks, switch to promise or synchronous usage.
gotcha The tagged template literal watr`...` does NOT accept arbitrary JavaScript expressions inside WAT; only interpolations of JS functions or primitive values (BigInt, typed arrays, etc.) are supported. ↓
fix Use interpolations for imports or constants only; do not embed dynamic code generation via string concatenation inside template literal — use compile() with string building instead.
deprecated The 'polyfill' option in compile() may be deprecated or renamed in future versions. ↓
fix Use polyfill: false/true for now; check changelog for future changes.
gotcha ESM-only: CommonJS require() will fail with Module not found or default export missing. ↓
fix Use dynamic import: const watr = await import('watr'); or switch to ESM.
breaking v3.0.0 introduced full spec support, breaking many WAT snippets that relied on earlier non-standard sugar or missing features. ↓
fix Validate WAT against the WebAssembly spec; use the official test suite or watr's parse to check.
Install
npm install watr yarn add watr pnpm add watr Imports
- watr (default) wrong
const watr = require('watr')correctimport watr from 'watr' - compile wrong
import { compile } from 'watr/compile'correctimport { compile } from 'watr' - parse wrong
import parse from 'watr'correctimport { parse } from 'watr' - print wrong
import { printTree } from 'watr'correctimport { print } from 'watr' - Type definitions wrong
import { WatNode } from 'watr'correctimport type { WatNode } from 'watr'
Quickstart
import watr, { compile, parse, print } from 'watr'
// 1. Compile WAT to binary
const binary = compile('(func (export "f") (result f64) (f64.const 1))', {
polyfill: false,
optimize: true
})
const module = new WebAssembly.Module(binary)
const { f } = new WebAssembly.Instance(module).exports
console.log(f()) // 1
// 2. Parse WAT to AST tree
const tree = parse('(i32.const 42)')
console.log(tree) // ['i32.const', 42]
// 3. Print (pretty-print) WAT
const prettified = print('(module(func(result i32)i32.const 42))')
console.log(prettified) // (module\n (func (result i32)\n i32.const 42\n )\n)
// 4. Use the tagged template for instant wasm
const { add } = watr`(func (export "add") (param i32 i32) (result i32)
(i32.add (local.get 0) (local.get 1))
)`
console.log(add(2, 3)) // 5
// 5. Auto-import JS functions
const { test } = watr`(func (export "test") (call ${console.log} (i32.const 42)))`
test() // logs 42