Skip to content

WASM Functions

WASM functions are registry entries that execute WebAssembly code. Two entry kinds are available: function.wat for inline WAT source and function.wasm for precompiled binaries.

Define small WASM functions directly in your _index.yaml using WebAssembly Text format:

entries:
- name: answer
kind: function.wat
source: |
(module
(func (export "answer") (result i32)
i32.const 42
)
)
wit: |
answer: func() -> s32;
method: answer
pool:
type: inline

For larger WAT sources, use a file reference:

- name: answer
kind: function.wat
source: file://answer.wat
wit: |
answer: func() -> s32;
method: answer
pool:
type: inline
FieldRequiredDescription
sourceYesInline WAT source or file:// reference
methodYesExported function name to call
witNoWIT signature for raw/core modules
poolNoWorker pool configuration
transportNoInput/output mapping (default: payload)
importsNoHost imports to enable (e.g., wasi:cli, wasi:io)
wasiNoWASI configuration (args, env, mounts)
limitsNoExecution limits

Load compiled .wasm binaries from a filesystem entry:

entries:
- name: assets
kind: fs.directory
directory: ./wasm
- name: compute
kind: function.wasm
fs: myns:assets
path: /compute.wasm
hash: sha256:292b796376f8b4cc360acf2ea6b82d1084871c3607a079f30b446da8e5c984a4
method: compute
pool:
type: lazy
max_size: 4
FieldRequiredDescription
fsYesFilesystem entry ID containing the binary
pathYesPath to .wasm file within the filesystem
hashYesSHA-256 hash for integrity verification (sha256:...)
methodYesExported function name to call
witNoWIT signature for raw/core modules
poolNoWorker pool configuration
transportNoInput/output mapping (default: payload)
importsNoHost imports to enable
wasiNoWASI configuration
limitsNoExecution limits

Each WASM function uses a pool of pre-compiled instances. The pool type controls concurrency and resource usage.

TypeDescription
inlineSynchronous, single-threaded. New instance per call.
lazyZero idle workers. Scales on demand up to max_size.
staticFixed number of workers with request queue.
adaptiveAuto-scaling elastic pool.
pool:
type: static
size: 4 # Total pool size
workers: 2 # Worker threads
buffer: 16 # Request queue buffer (default: workers * 64)
pool:
type: lazy
max_size: 8 # Maximum concurrent instances
pool:
type: adaptive
max_size: 16 # Upper scaling bound

The 100-worker default applies only to the implicitly selected pool (when no type is set). When you explicitly set type: lazy or type: adaptive without max_size, the default maximum is 16 workers.

Transports control how input and output are mapped between the runtime and the WASM module.

TransportDescription
payloadMaps runtime payloads directly to WASM call arguments (default)
wasi-httpMaps HTTP request/response context to WASM arguments and results

The default transport passes arguments directly. Lua values are transcoded to Go types, then lowered to WIT types:

- name: compute
kind: function.wasm
fs: myns:assets
path: /compute.wasm
hash: sha256:...
method: compute
pool:
type: inline
-- Arguments passed directly as WASM function parameters
local result, err = funcs.call("myns:compute", 6, 7)
-- result: 42

The wasi-http transport maps HTTP requests to WASM and writes results back to the HTTP response. Use this to expose WASM functions as HTTP endpoints:

- name: greet_wasm
kind: function.wasm
fs: myns:assets
path: /greet.wasm
hash: sha256:...
method: greet
transport: wasi-http
pool:
type: inline
- name: greet_endpoint
kind: http.endpoint
method: POST
path: /api/greet
func: greet_wasm

Set a maximum execution time for a function:

limits:
max_execution_ms: 5000 # 5 second timeout

When the limit is exceeded, the execution is cancelled and an error is returned.

Configure WASI capabilities for the guest module:

wasi:
args: ["--verbose"]
cwd: "/app"
env:
- id: myns:api_key
name: API_KEY
required: true
- id: myns:debug_mode
name: DEBUG
mounts:
- fs: myns:data_files
guest: /data
read_only: true
- fs: myns:output
guest: /output
FieldDescription
argsCommand-line arguments passed to the guest
cwdWorking directory inside the guest (must be absolute)
envEnvironment variables mapped from registry env entries
mountsFilesystem mounts from registry filesystem entries

Environment variables are resolved from the environment registry at call time. Required variables cause an error if not found.

Mount paths must be absolute and unique. Each mount maps a runtime filesystem entry to a guest directory path.

entries:
- name: wasm_binaries
kind: fs.directory
directory: ./wasm
- name: transform_users
kind: function.wasm
fs: myns:wasm_binaries
path: /mapper.wasm
hash: sha256:7304fc7d19778605458ae5804dae9a7343dcd3f5fc22bcc9415e98b5047192dd
method: transform-users
pool:
type: lazy
max_size: 4
- name: filter_active
kind: function.wasm
fs: myns:wasm_binaries
path: /mapper.wasm
hash: sha256:7304fc7d19778605458ae5804dae9a7343dcd3f5fc22bcc9415e98b5047192dd
method: filter-active
pool:
type: lazy
max_size: 4
local funcs = require("funcs")
local users = {
{id = 1, name = "Alice", tags = {"admin", "dev"}, active = true},
{id = 2, name = "Bob", tags = {"user"}, active = false},
{id = 3, name = "Carol", tags = {"dev"}, active = true},
}
-- Transform: adds display field and tag count
local transformed, err = funcs.call("myns:transform_users", users)
-- Filter: returns only active users
local active, err = funcs.call("myns:filter_active", users)

WASM components that import wasi:clocks and wasi:io can use clocks and polling. The async yield mechanism integrates with the Wippy dispatcher:

- name: sleep_ms
kind: function.wasm
fs: myns:wasm_binaries
path: /sleep_test.wasm
hash: sha256:...
method: "test-sleep#sleep-ms"
imports:
- wasi:io
- wasi:clocks
pool:
type: inline

The # separator in the method field references an interface method: test-sleep#sleep-ms calls the sleep-ms function from the test-sleep interface.