Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

WASM plugins

A task can be implemented by a WebAssembly plugin — write it in any language that compiles to wasm32, ship a single .wasm, and run it anywhere yatr runs:

[tasks.codegen]
wasm = "plugins/codegen.wasm"                         # local path
[tasks.shared]
wasm = "https://example.com/v1/plugin.wasm"            # …or an http(s) URL
[tasks.gh]
wasm = "github:owner/repo@v1.0.0/plugin.wasm"          # …or a GitHub release asset

Plugins are capability-sandboxed: they run in a pure-Rust interpreter (wasmi) with only yatr’s host ABI imported — no filesystem, network, or clock. A plugin that tries to import anything else fails to load, so even an untrusted remote plugin can’t escape. Remote plugins are downloaded once and cached (override with YATR_PLUGIN_DIR); plugin output is captured and cached like any task.

Host ABI

A plugin exports its memory and run() -> i32 (0 = success), and may import:

ImportSignatureEffect
emit(ptr, len)Append a UTF-8 string to the task’s output
log(ptr, len)Log an info message
input_len() -> i32Byte length of the task input
input_read(ptr) -> i32Copy the input (JSON {task, env}) into memory

Writing plugins in Rust

The yatr-plugin crate wraps the raw ABI so you write plain Rust:

#![allow(unused)]
fn main() {
yatr_plugin::plugin!({
    let input = yatr_plugin::input_string();  // {"task":...,"env":{...}}
    yatr_plugin::emit(&format!("hello from a plugin; input = {input}"));
    Ok(())
});
}
cargo build --release --target wasm32-unknown-unknown

Then point a task at the resulting .wasm.