| name | wasm-wasmtime |
| description | WebAssembly runtime skill using wasmtime. Use when running WASM modules with wasmtime CLI, working with WASI preview2, using the component model, embedding wasmtime in Rust applications, limiting execution with fuel metering, or debugging WASM with DWARF in wasmtime. Activates on queries about wasmtime, WASI, WASM component model, wasmtime embedding, WIT interfaces, fuel metering, or server-side WebAssembly. |
wasmtime — Server-Side WASM Runtime
Purpose
Guide agents through wasmtime: running WASM modules from the CLI, WASI APIs, the component model with WIT interfaces, embedding wasmtime in Rust applications, fuel metering for sandboxed execution, and debugging WASM with DWARF debug info.
Triggers
- "How do I run a WASM file with wasmtime?"
- "How does WASI work with wasmtime?"
- "How do I embed wasmtime in my Rust application?"
- "What is the WebAssembly component model?"
- "How do I limit WASM execution with fuel?"
- "How do I debug a WASM module in wasmtime?"
Workflow
1. wasmtime CLI
curl https://wasmtime.dev/install.sh -sSf | bash
wasmtime hello.wasm
wasmtime prog.wasm -- arg1 arg2
wasmtime --dir /tmp::/ prog.wasm
wasmtime --env HOME=/home/user prog.wasm
wasmtime run --invoke add math.wasm 3 4
wasmtime explore math.wasm
wasmtime inspect math.wasm
wasmtime compile prog.wasm -o prog.cwasm
wasmtime run prog.cwasm
2. WASI preview2 APIs
WASI preview2 provides a capability-based POSIX-like API set:
wasmtime --wasi-modules experimental-wasi-http prog.wasm
3. Embedding wasmtime in Rust
[dependencies]
wasmtime = "24"
wasmtime-wasi = "24"
anyhow = "1"
use wasmtime::*;
use wasmtime_wasi::WasiCtxBuilder;
fn main() -> anyhow::Result<()> {
let engine = Engine::default();
let module = Module::from_file(&engine, "prog.wasm")?;
let wasi = WasiCtxBuilder::new()
.inherit_stdio()
.inherit_env()
.preopened_dir("/tmp", "/")?
.build();
let mut store = Store::new(&engine, wasi);
let instance = Instance::new(&mut store, &module, &[])?;
let add = instance.get_typed_func::<(i32, i32), i32>(&mut store, "add")?;
let result = add.call(&mut store, (, ))?;
();
(())
}
4. Fuel metering — CPU limiting
Fuel metering limits the number of WASM instructions executed, preventing runaway or malicious code:
use wasmtime::*;
let mut config = Config::default();
config.consume_fuel(true);
let engine = Engine::new(&config)?;
let module = Module::from_file(&engine, "untrusted.wasm")?;
let mut store = Store::new(&engine, ());
store.set_fuel(1_000_000)?;
let instance = Instance::new(&mut store, &module, &[])?;
let run = instance.get_typed_func::<(), ()>(&mut store, "run")?;
match run.call(&mut store, ()) {
Ok(_) => println!("Completed, fuel remaining: {}", store.get_fuel()?),
Err(e) if e.to_string().contains("all fuel consumed") => {
println!("Timed out (fuel exhausted)");
}
Err(e) => eprintln!("Error: {e}"),
}
5. Component model and WIT
The component model adds typed interface definitions (WIT) on top of core WASM:
// math.wit — interface definition
package example:math@1.0.0;
interface calculator {
add: func(a: s32, b: s32) -> s32;
sqrt: func(x: f64) -> f64;
}
world math-world {
export calculator;
}
cargo install wasm-tools cargo-component
cargo component new --lib math-component
cargo component build --release
wasmtime run math-component.wasm
use wasmtime::component::*;
wasmtime::component::bindgen!({
world: "math-world",
path: "math.wit",
});
let component = Component::from_file(&engine, "math.wasm")?;
let (calculator, _) = MathWorld::instantiate(&mut store, &component, &linker)?;
let result = calculator.call_add(&mut store, 3, 4)?;
6. WASM debugging with DWARF
cargo build --target wasm32-wasi
WASMTIME_BACKTRACE_DETAILS=1 wasmtime prog.wasm
wasmtime --debug-info prog.wasm 2>&1
wasmtime debug prog.wasm
wasm-tools print prog.wasm | head -50
wasm-tools validate prog.wasm
7. WASM GC (garbage-collected objects)
WASM GC proposal adds struct and array types with managed allocation:
;; GC-enabled module (toolchain dependent)
(struct $point (field (mut f32) x) (field (mut f32) y))
wasm-tools validate --features gc module.wasm
wasmtime run --wasm gc module.wasm
In Rust/component builds, check wasmtime feature flags for gc support. Use struct.new, array.new, struct.get, array.get instructions in WAT or compiled output.
8. WASM threads and shared memory
clang --target=wasm32-wasi -pthread -matomics -mbulk-memory -o prog.wasm prog.c
wasmtime run prog.wasm
Atomics (i32.atomic.*) and memory.atomic.wait/notify require bulk-memory and threads proposals. Check wasmtime --help for -W/-S overrides if running an older build.
9. WASM exception handling
(try (do $exn)
(throw $exn)
(catch $exn (local.get 0) (return)))
wasmtime run module.wasm
Replaces longjmp-style Emscripten patterns with native try/catch/throw in WASM. For embedding, enable explicitly if needed:
config.wasm_exceptions(true);
10. WASI Preview 2 (p2) stabilization
WASIp2 uses the component model with typed interfaces instead of raw syscall imports:
wasmtime run component.wasm
wit-bindgen rust ./deps/wasi-cli.wit
Migrate from WASI p1 (wasi_snapshot_preview1) by regenerating bindings with cargo component and WIT packages.
11. Performance configuration
let mut config = Config::default();
config.cranelift_opt_level(OptLevel::SpeedAndSize);
config.parallel_compilation(true);
config.cache_config_load_default()?;
let serialized = module.serialize()?;
std::fs::write("prog.cwasm", &serialized)?;
let module = unsafe { Module::deserialize_file(&engine, "prog.cwasm")? };
Related skills
- Use
skills/runtimes/wasm-emscripten for compiling C/C++ to WASM for browser/WASI
- Use
skills/rust/rust-async-internals for async patterns in wasmtime Rust embedding
- Use
skills/runtimes/binary-hardening for sandboxing considerations with WASM