Skip to content

Export Functions

On this page

The @export decorator marks a function to be exposed as a public symbol of the wasm module. With --aot --host browser mode, the compiler generates:

  • 03-export.wasm — the compiled module
  • 03-export.js — typed JS wrappers for each @export function
  • 03-export.d.ts — corresponding TypeScript declarations

On the JS/TS side, usage feels natural:

import init, { fib, greet, even } from './03-export.js';
await init(); // instantiate the module
fib(10); // 55
greet('Zolo'); // "Hello, Zolo!"
even(4); // true

Boundary types (MVP): intnumber, boolboolean, strstring, and void return. Strings cross the boundary via generated glue (the loader writes the JS string into wasm memory and reads the result back); int and bool cross directly. Any other type in an @export function (float, arrays, structs) fails the build with E_WasmAotUnsupportedFeature.

Top-level code continues to run in zolo_main() — call it from JS if you need the initialization side effect:

Three @export functions with scalar boundary types: int, str, and bool.

03-export.zolo
// Feature: export Zolo functions to JS/TS — `@export` (AOT wasm)

// Syntax: `@export fn name(args) -> T { ... }`

// When to use: build a Zolo library that JavaScript/TypeScript calls directly.

//

// Build (AOT, browser):

//   zolo build 32-webassembly/03-export.zolo --emit wasm --host browser --aot \

//     -o 32-webassembly/target/03-export.wasm

//   # -> 03-export.wasm + 03-export.js (typed wrappers) + 03-export.d.ts

//

// Then from JS/TS:

//   import init, { fib, greet, even } from "./03-export.js"

//   await init()              // instantiate the module

//   fib(10)                   // 55

//   greet("Zolo")             // "Hello, Zolo!"

//   even(4)                   // true

//

// Boundary types (MVP): int <-> number, bool <-> boolean, str <-> string,

// and a void return. Anything else on an @export (float, arrays, structs)

// fails the build with E_WasmAotUnsupportedFeature. Strings cross via the

// generated glue (it writes the JS string into wasm memory and reads results

// back); int/bool cross directly. `print` still goes to the console.


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

@export
fn greet(name: str) -> str {
  return "Hello, {name}!"
}

@export
fn even(n: int) -> bool {
  return n % 2 == 0
}

// Top-level code still runs on `zolo_main()` (call it from JS if you want it).

"03-export loaded" |> print()

// expected (run natively): 03-export loaded

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

Challenge

Add a fourth @export fn square(n: int) -> int that returns n * n. Recompile and confirm that it appears in the generated .d.ts.

Search Zolo

9 results

enespt-br