Stream: general

Topic: Traits for adding host function interfaces


view this post on Zulip Lachlan Gunn (Feb 12 2026 at 15:57):

I'm involved in a project where we are building a bunch of different host interfaces that will ultimately all need to be linked into to a single Wasmtime runtime. An idea that I've been toying with is to come up with a single trait that each crate will implement for its host interfaces, so that we can compose them all together without having to manually define views into the Store<T>'s T.

I've been experimenting with a macro that lets you encapsulate all the additions to the runtime in a common trait implementation on the host interface's state to go in the Store:

#[derive(Default)]
struct CounterState(i64);
impl HostInterface for CounterState {
    fn link<T: HostInterfaceStateView<Self>>(linker: &mut wasmtime::component::Linker<T>) {
        // Add host functions to the linker
    }
}

#[derive(Default)]
struct StaticState(i64);
impl HostInterface for StaticState {
    fn link<T: HostInterfaceStateView<Self>>(linker: &mut wasmtime::component::Linker<T>) {
        // Add host functions to the linker
    }
}

Then you can compose them together:

wasmtime_extensions! {
    struct MiniState (
        CounterState
    );
}

wasmtime_extensions! {
    struct State (
        MiniState,
        StaticState
    );
}

but also add them (edit: all at once) to a Linker with a single static method:

let state: State = Default::default();
let mut store = wasmtime::Store::new(&engine, state);
let mut linker = wasmtime::component::Linker::new(&engine);

State::link(&mut linker);

But before I go down the rabbit-hole of solving some of its limitations (mainly dealing with configuration) and learning to tidy it up into a proc macro that can be #[derive]ed, is there something out there like this already that I've somehow missed, that would allow these host interfaces to be encapsulated and then aggregated together in a more-or-less tidy way in the same way that wasmtime-wasi does?

view this post on Zulip Lachlan Gunn (Feb 12 2026 at 17:01):

Or is this something that might be better done using bindgen! directly?

view this post on Zulip Alex Crichton (Feb 12 2026 at 19:35):

One piece of inspiration I might recommend here is Spin Factors which while I haven't heavily used them myself I feel have done a really good job of enabling separate crates to build various implementations to get relatively easily woven in at the end

view this post on Zulip Lachlan Gunn (Feb 13 2026 at 06:16):

Thanks! I'll take a look

view this post on Zulip Lachlan Gunn (Feb 13 2026 at 08:28):

This looks great. Sadly it comes with a little bit of baggage from Spin that prevents it from being used as-is, but as you say, it looks like great inspiration, and I'm glad to have some confirmation that it's not a completely terrible idea. I had that doubt in my mind of _this seems obvious enough that if it were a good idea, then it would probably have been built into Wasmtime or some associated crate already_.


Last updated: Feb 24 2026 at 04:36 UTC