Hi. I'm trying to understand how to create a component which exports a resource in Rust. I may have misunderstandings at every stage, getting confused between guest/host, etc.!
Anyway, from this WIT:
package component:zipreader;
interface zip {
enum zip-error {
unknown
}
resource zipfile {
list-files: func() -> list<string>;
}
}
world zipread {
use zip.{zip-error, zipfile};
export zip;
export open: func(path: string) -> result<zipfile, zip-error>;
}
and using wit-bindgen as:
::wit_bindgen::generate!({
exports: {
world: ZipWorld,
"component:zipreader/zip/zipfile": MyZipfile,
},
});
The generated World trait is:
pub trait Guest {
fn open(path: wit_bindgen::rt::string::String) -> Result<Zipfile, ZipError>;
}
The open method needs to return a component::zipreader::zip::Zipfile, which is a generated type containing a handle: Resource<Zipfile>. How are you meant to turn an instance of the actual type (MyZipfile in this example) into the generated type? It seems like something similar to the wasmtime ResourceTable would fit the bill (or, for my purposes, a Vec<MyZipfile> would be fine) to get an id - but there's nowhere to store that as the open doesn't take any self type. What am I missing?
I believe if you follow the various type aliases you should be able to do Resource::new(MyZipFile::new(...)), although I agree it's a bit confusing.
If you'd like I just published wit-bindgen 0.20.0 today which I think might simplify this a bit, the exports field is removed and the compiler error messages and documentation should be a bit clearer about how to implement this. For example Zipfile, a generated type, will have a function Zipfile::new.
The 0.20.0 docs have some more documentation so there's an example of bindings for an exported resource which generates this API which should give you a ::new method where you'll implemente GuestZipfile for your MyZipfile type.
Thanks.
There is a Zipfile::new, but it's on exports::component::zipreader::zip::Zipfile, not component::zipreader::zip::Zipfile which is a different type and is the one being returned from Guest::open.
I think, anyway - I'm browsing the output from cargo expand.
aha I think you'll want to reorganize slightly actually
this is subtle, but the use statement in your world is actually importing a different copy of hte zip interface than the one you're exporting
so the open function is actually referring to a totally different zipfile type than the one that you have exportf or
You can read a bit more about this issue at https://github.com/WebAssembly/component-model/pull/308, but more-or-less I'd recommend moving the open method to the zip interface
I'll look at that and look more tomorrow. Thanks for the quick responses!
Ok, so just to check my understanding: currently, WIT doesn't support exporting a function from a world, which returns a resource from an exported interface. This will eventually be possible (and is possible in the component model).
Correct!
Last updated: Dec 06 2025 at 06:05 UTC