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.

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.
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.
npm install watr
yarn add watr
pnpm add watr

Compiles WAT to binary, parses to AST, pretty-prints, and uses tagged template for instant wasm with JS interop.

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