Skip to content

34 · WebAssembly

Host Profiles

Select the runtime profile with `--host wasi|browser` and enable the experimental AOT backend with `--aot`.

On this page

The toolchain supports two host profiles and an alternative compilation mode:

Flag Output When to use
--host wasi single .wasm WASI runtimes (wasmtime, etc.) — default
--host browser .wasm + .js + .d.ts import from a web application
--aot wasm without embedded VM experimental ZoloIR→wasm backend

--host browser mode generates JavaScript glue and TypeScript types alongside the .wasm, letting you import the module directly in TS/JS. --aot mode swaps the VM-embedded payload for the experimental native backend: supports integer arithmetic, recursion, if/while, string literals, and print.

The following example demonstrates all three modes with a simple recursive fib function, ideal for verifying that control-flow logic works correctly in each profile:

fib(10) with the three modes: WASI, browser, and AOT.

02-host-profiles.zolo
// Feature: wasm host profiles & AOT — `--host` / `--aot`

// Syntax: `zolo build file.zolo --emit wasm --host wasi|browser|node [--aot]`

// When to use: target a WASI runtime, browser, Node, or opt into the

//   experimental ahead-of-time ZoloIR->wasm backend.


// Run:

//   zolo build 32-webassembly/02-host-profiles.zolo --emit wasm --host wasi

//     # -> 02-host-profiles-0.0.0.wasm   (WASI host profile, the default)

//

//   zolo build 32-webassembly/02-host-profiles.zolo --emit wasm --host browser

//     # -> .wasm + .js + .d.ts  (browser glue for import in a web app)

//   zolo build 32-webassembly/02-host-profiles.zolo --emit wasm --host node

//     # -> .wasm + .mjs + .d.ts (Node ESM loader)

//

//   zolo build 32-webassembly/02-host-profiles.zolo --emit wasm --aot --host browser

//     # pure-wasm AOT (no embedded VM). Runs the supported subset: int math,

//     # recursion, if/while, string literals, and print. Serve over http and

//     # import the generated .js, or run with node:

//     #   node crates/zolo-wasm-aot/tests/run_wasm.mjs <file>.wasm   -> fib(10) =\t55

//

// host=wasi   -> a single .wasm wired for a WASI runtime (wasmtime, etc.)

// host=browser-> .wasm plus generated `.js` loader and `.d.ts` types so

//                you can `import` it from TypeScript/JS.

// --aot       -> swaps the VM-embedded payload for the experimental

//                ZoloIR-native wasm backend.


fn fib(n: int) -> int {
  if n < 2 { return n }
  return fib(n - 1) + fib(n - 2)
}

print("fib(10) =", fib(10))
// expected (run natively): fib(10) =	55

Requires the Zolo CLI/host — open in the playground or run locally.

To explore the AOT performance ceiling, the fibonacci.zolo file pushes the computation to Fibonacci of very large numbers via matrix exponentiation with BigInt — and also uses std::os::clock() to measure time:

O(log n) Fibonacci with BigInt and timing; illustrates std::os as the only wasm-safe API.

fibonacci.zolo
// Feature: wasm host profiles & AOT — `--host` / `--aot`

// Syntax: `zolo build file.zolo --emit wasm --host wasi|browser|node [--aot]`

// When to use: target a WASI runtime, browser, Node, or opt into the

//   experimental ahead-of-time ZoloIR->wasm backend.


// Run:

//   zolo build 32-webassembly/02-host-profiles.zolo --emit wasm --host wasi

//     # -> 02-host-profiles-0.0.0.wasm   (WASI host profile, the default)

//

//   zolo build 32-webassembly/02-host-profiles.zolo --emit wasm --host browser

//     # -> .wasm + .js + .d.ts  (browser glue for import in a web app)

//

//   zolo build 32-webassembly/02-host-profiles.zolo --emit wasm --aot --host browser

//     # pure-wasm AOT (no embedded VM). Runs the supported subset: int math,

//     # recursion, if/while, string literals, and print. Serve over http and

//     # import the generated .js, or run with node:

//     #   node crates/zolo-wasm-aot/tests/run_wasm.mjs <file>.wasm   -> fib(10) =\t55

//

// host=wasi   -> a single .wasm wired for a WASI runtime (wasmtime, etc.)

// host=browser-> .wasm plus generated `.js` loader and `.d.ts` types so

//                you can `import` it from TypeScript/JS.

// --aot       -> swaps the VM-embedded payload for the experimental

//                ZoloIR-native wasm backend.


// Fibonacci via matrix exponentiation (O(log n)) with BigInt

//

// Matrix [[a,b],[c,d]] stored as flat array [a, b, c, d]


// Multiply matrix a by matrix b, store result in a

fn mat_mul(a, b) {
  let x = a[0] * b[0] + a[1] * b[2]
  let y = a[0] * b[1] + a[1] * b[3]
  let z = a[2] * b[0] + a[3] * b[2]
  let w = a[2] * b[1] + a[3] * b[3]

  a[0] = x
  a[1] = y
  a[2] = z
  a[3] = w
}

// Square matrix a in-place

fn mat_square(a) {
  let x = a[0] * a[0] + a[1] * a[2]
  let y = a[0] * a[1] + a[1] * a[3]
  let z = a[2] * a[0] + a[3] * a[2]
  let w = a[2] * a[1] + a[3] * a[3]

  a[0] = x
  a[1] = y
  a[2] = z
  a[3] = w
}

// Raise matrix f to the power n using fast exponentiation

fn mat_power(f, n) {
  if n <= 1 {
    return
  }

  let one = 1n
  let zero = 0n
  let m = [one, one, one, zero]

  mat_power(f, n ~/ 2)
  mat_square(f)
  if n % 2 != 0 {
    mat_mul(f, m)
  }
}

// Compute the n-th Fibonacci number using BigInt

fn fibonacci(n) {
  if n == 0 {
    return 0n
  }

  let one = 1n
  let zero = 0n
  let f = [one, one, one, zero]
  mat_power(f, n - 1)
  return f[0]
}

// --- Main ---


struct Console(start: {str: float}) {
  fn new() {
    Self { start: #{} }
  }

  fn time(self, name) {
    self.start[name] = std::os::clock()
  }

  fn time_end(self, name) {
    print("time = ", std::os::clock() - self.start[name])
  }
}

fn main() {
  let console = Console::new()
  console.time("fibo")

  300_000_000
    |> fibonacci()
    |> tostring()
    |> .len()
    |> |v| "len: {v}"
    |> print()

  console.time_end("fibo")
}

Requires the Zolo CLI/host — open in the playground or run locally.

Challenge

Compile 02-host-profiles.zolo with --host browser and inspect the three generated files (.wasm, .js, .d.ts). What TypeScript signature is generated for the fib function?

Global index

Find your way through Zolo

Try an idea

Start here

9 results

9 results

enespt-br