I'm trying to design a toy system that supports plugins supplied by different authors.
Based on my current understanding of the component model, a way to achieve this would be to define a world (plugin) and accept .wasm components that implement that world. I would then compose these together with the 'main' .wasm component to create my program. Unfortunately, I'm having difficulty finding a way to achieve this in practice.
I can imagine rolling my own plugin registration system something like the following:
// There is a resource that defines the desired plugin API
resource plugin-resource {
// ...methods...
}
// Plugin authors implement components that know how to initialize
// their plugin-resource implementation.
world plugin {
init: func() -> plugin-resource;
}
// At composition time, some external logic chains together the provided
// plugins into one big component that satisfies this API.
world plugin-iterator {
next: func() -> option<plugin-resource>;
}
However, this feels pretty clunky. Before I go down that road, am I missing a supported way to achieve this? If there is no supported way to achieve this, is that a point-in-time limitation, or a design decision?
Thanks!
I think you'll run into a few limitations with this design. One is that, you're correct, dynamically composing a variable number of components to something that returns a list is not a simple wac command, for example, today. You'd have to have some sort of custom interposing component there.
Another issue, however, is that if each plugin exports the plugin-resource type then despite having the same WIT type at runtime they all have distinct types and aren't interchangeable. That means that at a type-level you can't actually implement plugin-iterator because each plugin would return a uniquely-typed plugin-resource.
What you might want instead is to have the host arbitrate this. The guest would import a single plugin-resuorce interface and would have a sort of "lookup" that the host would dispatch to other plugins. Basically "host magic" to help do the dispatch
Another issue, however, is that if each plugin exports the
plugin-resourcetype then despite having the same WIT type at runtime they all have distinct types and aren't interchangeable. That means that at a type-level you can't actually implementplugin-iteratorbecause each plugin would return a uniquely-typedplugin-resource.
Oh, interesting. I had been thinking of resources as values using dynamic dispatch over their resource {...} methods. Thank you for pointing this out, it's important to know.
What you might want instead is to have the host arbitrate this. The guest would import a single
plugin-resuorceinterface and would have a sort of "lookup" that the host would dispatch to other plugins. Basically "host magic" to help do the dispatch
Sorry, I'm not quite sure what you mean. Could you give me an example?
Effectively what you're imagining is dynamic dispatch could be implemented in the host. The component-model itself doesn't have that degree of dynamic dispatch but you on the host could have a trait which is implemented for each plugin. The guest would then import functionality that the host implements in terms of a list of trait objects. Or... something like that, not really an example per se as this is still pretty hand-wavy
Ok, thanks! I'll do some experimenting and see what I can figure out. In the meantime, are there any WIT features coming in the future that might facilitate composing an arbitrary number of components?
Not that I know of myself, no, unfortunately
Some flavor of WIT templates would probably help here.
Last updated: Dec 06 2025 at 06:05 UTC