Export Functions
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 module03-export.js— typed JS wrappers for each@exportfunction03-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): int ↔ number, bool ↔ boolean,
str ↔ string, 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.
// 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.
See also