Hi All,
I’ve started looking into tooling support for donut wrapping, where a component A imports another component B and instantiates B inside A. This allows A to both provide B’s imports and use its exports. Donut wrapping is already supported by the component model but not by tooling. Here’s an example (by Luke Wagner) of how it’s done in WAT:
(component
(core module $M ...)
(core instance $m (instantiate $M ...))
(core table $core_tbl (alias export $m "tbl"))
(core func $core_f (alias export $m "f"))
(func $f (canon lift ... (func $core_f))))
(import "guest" (component $Guest ...))
(instance $guest (instantiate $Guest (with "f" (func $f))))
(func $g (alias export $guest "g"))
(core func $core_g (canon lower ... (func $g)))
(core module $Util
(import "" "tbl" (table $t funcref 0))
(import "" "g" (func $g ...))
(elem (table $t) $g)
)
(core instance $util (instantiate $Util (with "" (instance
(export "tbl" (table $core_tbl))
(export "g" (func $core_g))
))
)
Here, a core instance $m is providing imports to $guest and calls its exports through a core table via $Util.
I’m thinking about following these steps:
First, we need to express “component imports” in WIT. For this, I suggest extending WIT to support import world w; statements in world definitions, where a world imports a component described by a world w.
Next, wit-parser must be modified to support the import world statement, and wit-component must be modified accordingly. This includes adding WorldKey::World and WorldItem::World cases in wit-parser and changing Resolve accordingly. This will ultimately result in (import "guest" (component ...)) in CM.
Then, wit-bindgen must be changed to consume importing worlds and to generate the component (I haven’t looked into this carefully yet).
I’d like to hear your thoughts and get your feedback before starting the implementation. Some questions are:
What are your thoughts about the suggested import world syntax? What are some possible alternatives?
Is there a process that I should follow (including GitHub issues, reference implementations, etc.)?
Am I missing anything in the way that I’m approaching this problem? Are there other alternative or more efficient ways of doing this?
Thanks!
Last updated: Dec 06 2025 at 06:05 UTC