Use when running WASM with the wasmtime CLI, embedding wasmtime in Rust, limiting execution with fuel, or building WASI preview2 components. Not for browser targets: use wasm-emscripten.
Scanned 9/12/2026
Install to Claude Code
npx -y skills add OutlineDriven/odin-claude-plugin --skill wasm-wasmtime --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Wasm Wasmtime?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/outlinedriven-wasm-wasmtime)More formats (shields.io, HTML) on the badges page.
---
name: wasm-wasmtime
description: 'Use when running WASM with the wasmtime CLI, embedding wasmtime in Rust, limiting execution with fuel, or building WASI preview2 components. Not for browser targets: use wasm-emscripten.'
---
# wasmtime
## Contract
| Field | Bound contract |
|---|---|
| Trigger | Server-side WebAssembly with wasmtime: CLI execution and AOT compilation, WASI capabilities, component model with WIT, Rust embedding, fuel metering, or DWARF-based diagnosis. |
| Authority | Reversible local. Writes are limited to compiled artifacts, serialized modules, and project build outputs; rollback is deleting those files. No remote mutation. |
| Side effect | `.cwasm` artifacts, Rust build outputs, and host binaries that embed wasmtime. |
| Done | The module or component runs under wasmtime with named capabilities, or the embedding builds and enforces its execution limits. |
## Inputs
1. Module or component (required): the `.wasm` to run, or the WIT world to build.
2. Capabilities (required for WASI): directories, environment, sockets, and HTTP the guest may use.
3. wasmtime version (required): `wasmtime --version`. Grounded: 48.0.0 (current, LTS); releases monthly; Wasm GC and exceptions are on by default since 47.
4. Trust level (optional): untrusted guest code drives fuel or epoch decisions in step 5.
## Procedure
1. Run and inspect from the CLI. Wasmtime flags go before the module path; everything after the module is a guest argument:
```bash
wasmtime hello.wasm
wasmtime prog.wasm -- arg1 arg2
wasmtime --dir . prog.wasm # preopen the current directory
wasmtime --dir /tmp::/ prog.wasm # host /tmp mapped to guest /
wasmtime --env HOME=/home/user prog.wasm
wasmtime run --invoke add math.wasm 3 4 # call one core export
wasmtime explore math.wasm # emit an HTML code explorer
```
`--dir` grants read-write access to the mapped host directory; treat every preopen as a capability grant. Done when: the module runs with exactly the capabilities it asked for.
2. Compile ahead of time for fixed deployments, and inspect the output with the built-in disassembler:
```bash
wasmtime compile prog.wasm -o prog.cwasm
wasmtime prog.cwasm
wasmtime objdump prog.cwasm # native code, annotated
```
A `.cwasm` file only loads on hosts matching the compile target. Done when: the deployment artifact loads and the startup compilation cost is gone.
3. Serve HTTP components with the `serve` subcommand, which runs the `wasi:http/proxy` world:
```bash
wasmtime serve --addr=0.0.0.0:8081 component.wasm
```
The CLI server is for development; put a real reverse proxy with limits in front of production traffic. Done when: the component answers a request through wasi:http or the constraint is recorded.
4. Embed wasmtime in Rust. Current API lines (48.x), including the `FsPerms` argument on preopens:
```toml
[dependencies]
wasmtime = "48"
wasmtime-wasi = "48"
```
```rust
use wasmtime::*;
fn main() -> anyhow::Result<()> {
let engine = Engine::default();
let module = Module::from_file(&engine, "prog.wasm")?;
let mut store = Store::new(&engine, ());
let instance = Instance::new(&mut store, &module, &[])?;
let add = instance.get_typed_func::<(i32, i32), i32>(&mut store, "add")?;
println!("{}", add.call(&mut store, (3, 4))?);
Ok(())
}
```
For WASI guests, build a `WasiCtxBuilder` context and grant capabilities explicitly; `preopened_dir` takes host path, guest path, then `FsPerms::ReadOnly` or `FsPerms::ReadWrite`, and `build_p1()` produces the context for legacy WASIp1 modules:
```rust
use wasmtime_wasi::{WasiCtxBuilder, FsPerms};
let wasi = WasiCtxBuilder::new()
.inherit_stdio()
.inherit_env()
.preopened_dir("/tmp", "/", FsPerms::ReadWrite)?
.build();
```
Done when: the embedding builds against the pinned versions and grants only the listed capabilities.
5. Limit untrusted execution deterministically with fuel, or by wall clock with epochs. Fuel counts instructions; epochs suit pure timeout enforcement:
```rust
use wasmtime::*;
let mut config = Config::default();
config.consume_fuel(true);
let engine = Engine::new(&config)?;
let mut store = Store::new(&engine, ());
store.set_fuel(1_000_000)?;
match run.call(&mut store, ()) {
Ok(_) => println!("done, fuel left: {}", store.get_fuel()?),
Err(e) if e.downcast_ref::<Trap>() == Some(&Trap::OutOfFuel) => {
eprintln!("fuel exhausted");
}
Err(e) => eprintln!("error: {e}"),
}
```
A store starts with zero fuel; forgetting `set_fuel` traps immediately. Done when: the limit fires on the chosen budget and the error path is exercised.
6. Define and build components with WIT. The interface file is the contract; `cargo component` wraps it in a Rust crate, and the `bindgen!` macro generates the host side:
```wit
package example:math@1.0.0;
interface calculator {
add: func(a: s32, b: s32) -> s32;
}
world math-world {
export calculator;
}
```
```bash
cargo install wasm-tools cargo-component
cargo component new --lib math-component
cargo component build --release
wasmtime run math-component.wasm
```
```rust
wasmtime::component::bindgen!({ world: "math-world", path: "math.wit" });
```
Migrate a legacy WASIp1 module by regenerating bindings from WIT with `cargo component` or `wit-bindgen`; the raw `wasi_snapshot_preview1` imports are the marker of what needs migrating. Done when: the component instantiates through the typed interface on both sides.
7. Debug with the debug info the module carries. Build with debug info retained, then ask wasmtime for detailed backtraces; disassemble and validate with wasm-tools:
```bash
WASMTIME_BACKTRACE_DETAILS=1 wasmtime prog.wasm
wasm-tools print prog.wasm | head -50 # WAT disassembly
wasm-tools validate prog.wasm
```
Backtraces name wasm functions when the module keeps its name section. Done when: the fault maps to a function and offset in the module.
8. Use the post-47 defaults for GC, exceptions, and threads; no feature flags are needed on current releases. GC adds struct and array types (`struct.new`, `array.get`) for managed objects. Exceptions give WASM native `try`/`catch`/`throw`. Threads need the `wasm32-wasi-threads` target at build time:
```bash
clang --target=wasm32-wasi-threads -pthread -o prog.wasm prog.c
wasmtime run prog.wasm
```
Older runtimes may need `-W threads` and `-W exceptions`; check `wasmtime -W help` when the host version is below 47. Done when: the feature set is confirmed on the recorded wasmtime version, not assumed from the default.
9. Tune host-side performance. Cache compiled modules on disk, parallelize compilation, and serialize for deployment:
```rust
let mut config = Config::default();
config.cranelift_opt_level(OptLevel::SpeedAndSize);
config.parallel_compilation(true);
config.cache_config_load_default()?;
let serialized = module.serialize()?; // build pipeline
std::fs::write("prog.cwasm", &serialized)?;
let module = unsafe { Module::deserialize_file(&engine, "prog.cwasm")? }; // runtime
```
`deserialize_file` is unsafe because it trusts the file byte for byte; only load artifacts your own pipeline produced. Done when: startup time is measured before and after.
## Failure and recovery
| Failure class | Behavior |
|---|---|
| Instantiation fails on unknown import | A capability was not granted. Match each import to a `WasiCtxBuilder` setting or a linker entry. |
| `.cwasm` refuses to load | Host or CPU mismatch with the compile target. Recompile on the deployment host. |
| Traps immediately with zero fuel | `set_fuel` was never called. Set the budget before the first call. |
| Fuel check misses the error | The trap type is `Trap::OutOfFuel`; match by downcast, not by message text. |
| Component type mismatch | WIT worlds differ between sides. Regenerate bindings from one canonical WIT file. |
| Backtrace shows raw addresses | Name section stripped. Rebuild the module with names retained. |
## Output
The run or serve command with its capability list, the AOT artifact, or the embedding that builds and enforces its limits. Serialized modules carry a note about the trust their loading assumes. Every claim names the wasmtime release it assumes.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!