Hey :wave: I am exploring component composition following the component model docs, using cargo component and wasm-tools compose. While the tutorial (calculator component consumes an adder component) matches my understanding, I'm struggling to do the same when both components import from and export to the other respectively. Example:
interface.wit
interface a-to-b {
foo-AB: func() -> u32;
}
interface b-to-a {
foo-BA: func() -> u32;
}
interface a-ext {
entry: func() -> u32;
}
world A {
import b-to-a;
export a-to-b;
export a-ext;
}
world B {
import a-to-b;
export b-to-a;
}
with simple implementations
// implementation of A.entry
fn entry() -> u32 { foo_ba() }
// implementation of A.foo-ab
fn foo_ab() -> u32 { 42 }
// implementation of B.foo-ba
fn foo_ba() -> u32 { foo_ab() }
compiled with cargo component build --release, composed with
$ wasm-tools compose A.wasm -d B.wasm -d A.wasm -o composed.wasm
I expected a component which exports only a-ext (with entry returning 42) and no imports. However, the resulting components interface is
package root:component;
world root {
import test-interface:api/a-to-b;
export test-interface:api/a-to-b;
export test-interface:api/a-ext;
}
What am I missing?
wasm-compose does not currently support circular dependencies, so what you're trying to do is not (yet) possible. In theory, wasm-compose could be modified to support such things using e.g. a synthesized module with indirect function calls to "break" the cycle, but nobody has started working on that AFAIK.
Last updated: Dec 06 2025 at 06:05 UTC