The Wasm Component Model wraps WebAssembly modules in a typed composition layer. WIT defines higher-level interfaces so guest and host applications can exchange strings, options, and other structured values without manually agreeing on linear-memory layouts. section 3.0
A component-based application separates responsibilities across several runtime pieces:
- A WIT world describes the application interface, including imports and callable functions. section 3.0
- The host implements imported functionality, such as a key-value store with get and set operations. section 3.4.2
- Wasmtime configures and executes the component through an engine, store, component loader, and linker. section 3.4.2
- The linker connects host implementations to guest imports, allowing the guest component to call host functionality. section 3.4.2
SmartCMS host
A Rust SmartCMS host generates bindings from smart_cms.wit, implements the kvstore interface over a HashMap, enables Wasmtime's wasm_component_model feature, creates runtime state, loads guest.wasm, links the key-value implementation, and invokes the guest's run function. section 3.4.2
Listing 3.6 The full main.rs file for our SmartCMS host
wasmtime::component::bindgen!({ #1
path: "./smart_cms.wit",
world: "app",
});
struct KeyValue { #2
mem: std::collections::HashMap<String, String>, #2
}
impl component::smartcms::kvstore::Host for KeyValue {
fn get(&mut self, key: String) ->
➥Option<String> { #3
self.mem.get(&key).cloned()
}
fn set(&mut self, key: String, value: String) {
self.mem.insert(key, value);
}
}
struct State { #4
key_value: KeyValue,
}
fn main() {
let mut config = wasmtime::Config::default();
config.wasm_component_model(true); #5
let engine = wasmtime::Engine::new(&config).unwrap();
let mut store = wasmtime::Store::new
➥(&engine, State { key_value: KeyValue { mem:
➥ std::collections::HashMap::new() } }); #6
let component = wasmtime::component::
➥Component::from_file(&engine, "guest.wasm").unwrap();
let mut linker = wasmtime::component::Linker::new(&engine);
component::smartcms::kvstore::
➥add_to_linker(&mut linker, |state: &mut State| &mut
➥ state.key_value).unwrap(); #7
let app = App::instantiate(&mut store,
➥&component, &linker).unwrap(); #8
println!("{:?}", app.call_run(&mut store)
➥.unwrap()); #9
}
The complete Rust host listing shows how generated bindings, host state, Wasmtime configuration, component loading, linking, and guest invocation fit together. section 3.4.2
