Stream: wasi

Topic: Accepting an arbitrary number of plugins


view this post on Zulip zslayton (Oct 10 2025 at 12:18):

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!

view this post on Zulip Alex Crichton (Oct 10 2025 at 14:37):

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

view this post on Zulip zslayton (Oct 10 2025 at 16:11):

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.

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-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

Sorry, I'm not quite sure what you mean. Could you give me an example?

view this post on Zulip Alex Crichton (Oct 10 2025 at 16:16):

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

view this post on Zulip zslayton (Oct 10 2025 at 16:21):

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?

view this post on Zulip Alex Crichton (Oct 10 2025 at 16:23):

Not that I know of myself, no, unfortunately

view this post on Zulip Joel Dice (Oct 10 2025 at 16:34):

Some flavor of WIT templates would probably help here.

Motivation Let's say I'd like to build a component that consumes 3 configuration values a, b and c (which in a 12-factor app I'd take as 3 environment variables). I could define a component with ty...

Last updated: Dec 06 2025 at 06:05 UTC