This project demonstrates a WebAssembly component implementation using wit-bindgen and Rust, with a Wasmtime-based host application that supports debugging.
debug-wasm/
├── wasm-component/ # WebAssembly component (Rust) - math functions
│ ├── src/lib.rs # Component implementation
│ ├── wit/world.wit # WIT interface definition
│ └── Cargo.toml # Component dependencies
├── wasm-component-2/ # WebAssembly component (Rust) - calculator
│ ├── src/lib.rs # Component implementation
│ ├── wit/world.wit # WIT interface definition
│ └── Cargo.toml # Component dependencies
├── host-app/ # Host application (Rust)
│ ├── src/main.rs # Host implementation
│ ├── wit/world.wit # WIT interface for foo-world
│ ├── wit/calc-world.wit # WIT interface for calc-world
│ ├── build.rs # Build script for bindings
│ └── Cargo.toml # Host dependencies
├── wasm-module/ # Legacy core wasm module (C)
│ ├── foo.c # Simple C implementation
│ └── Makefile # Build script
└── .vscode/
└── launch.json # VS Code debug configuration
The WebAssembly component exports a simple foo function:
package component:foo;
interface math {
record key-value {
key: string,
value: string,
}
foo: func(x: s32) -> s32;
bar: func(keys: list<string>) -> list<key-value>;
}
world foo-world {
export math;
}The foo function takes an s32 parameter and returns x + 1.
The bar function takes a list of keys and returns key-value pairs.
The second WebAssembly component exports an add function:
package component:calc;
interface calculator {
add: func(a: s32, b: s32) -> s32;
}
world calc-world {
export calculator;
}The add function takes two s32 parameters and returns their sum.
rustup target add wasm32-wasip2
# Build wasm-component
cd wasm-component
cargo build --target wasm32-wasip2
# Build wasm-component-2
cd ../wasm-component-2
cargo build --target wasm32-wasip2cd host-app
cargo buildcd host-app
./target/debug/host-appExpected output:
🔧 Starting Wasmtime host app with debug enabled...
📦 Loaded component: ... bytes
🚀 Engine created with debug configuration
🧩 Component instantiated successfully
🔗 Linker created
⚡ Component bindings established
📞 Calling foo(41)...
✅ foo(41) = 42
📞 Calling bar(["username", "config", "session"])...
✅ bar() returned 3 key-value pairs:
📋 username -> default_value_for_username
📋 config -> default_value_for_config
📋 session -> default_value_for_session
🔧 Loading wasm-component-2...
📦 Loaded component-2: ... bytes
🧩 Component-2 instantiated successfully
⚡ Component-2 bindings established
📞 Calling add(10, 32)...
✅ add(10, 32) = 42
The host application enables Wasmtime debug features through environment variables:
WASMTIME_BACKTRACE_DETAILS=1: Detailed backtracesWASMTIME_LOG=debug: Debug logging
A launch configuration is provided in .vscode/launch.json for debugging the host application:
- Open the project in VS Code
- Set breakpoints in
host-app/src/main.rs - Press F5 or use "Debug Host App" configuration
- The debugger will stop at the first line (
stopOnEntry: true)
{
"name": "Debug Host App",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/host-app/target/debug/host-app",
"cwd": "${workspaceFolder}/host-app",
"env": {
"WASMTIME_BACKTRACE_DETAILS": "1",
"WASMTIME_LOG": "debug"
},
"stopOnEntry": true
}- Rust toolchain with wasm32-wasip2 target:
rustup target add wasm32-wasip2 - LLDB debugger for VS Code debugging
- VS Code with the C/C++ or CodeLLDB extension
The wasm-module/ directory contains the original C-based core WebAssembly module for comparison. It can be built with:
cd wasm-module
makeThis creates a traditional WebAssembly module that exports the same foo function but uses the core WebAssembly interface instead of the component model.