I am trying to wrap my head around using WASI with the component model and have some questions. Lets say I have a component written in Rust like:
package wasm-version-tests:component;
interface clients {
resource wasm-version-tests-client {
constructor();
hello-world: func() -> string;
}
}
world wasm-version-tests {
export clients;
}
wit_bindgen::generate!({
world: "wasm-version-tests",
exports: {
"wasm-version-tests:component/clients/wasm-version-tests-client": WasmVersionTestsClients,
},
use exports::wasm_version_tests::component::clients::GuestWasmVersionTestsClient;
pub struct WasmVersionTestsClients;
impl GuestWasmVersionTestsClient for WasmVersionTestsClients {
fn fetch_url(&self, url: String) -> String {
//Pretend fetch is doing an http call
let data = fetch(url);
return "Hello World".to_string();
}
fn new() -> Self {
WasmVersionTestsClients
}
}
This component performs an http call. If I compile this to wasm32-wasi and use jco transpile on the resulting binary, will the wasi:http shim automatically be included? Or do I need to specify an import wasi:http statement in my .wit file and use the imported wasi:http functions to handle all http traffic? I know in the wasm-bindgen era several crates (http ones specifically) had special compilation flags for wasm32 targets that let them work directly with the bindings, but as far as I can tell that doesn't seem to be a thing yet for wit and the component model.
@Landon James in order to depend on HTTP in WASI, you do indeed need to directly specify you depend on it.
What we did in the surf crate (one of the HTTP crates from the wasm-bindgen era) was to just assume that if you compiled with the bindgen flag on, that the js-sys/web-sys APIs would be present. This really wasn't great.
Actually, let me walk back my earlier statement a little bit perhaps
if you want to use wasi:http in Rust, you do need to import it directly. jco knows how to provide that interface, so you'll generally be fine if you do that.
A different way of doing this could be to just use the Rust stdlib's TCP abstraction, and bring your own HTTP stack. Doing this natively for WASI Preview 2 is likely going to be some work because afaik there are no async Rust runtimes which directly support it yet (the stdlib doesn't either). But it is possible to support it by targeting WASI Preview 1 and using the compat shim to allow it to work on Preview 2.
wrt jco: targeting Node.js should give you access to TCP sockets (though I think we might still be missing the TCP bind syscall in the implementation) - while targeting the browser will only give you access to the high-level HTTP interfaces (but the browser impl has been temporarily de-prioritized in favor of getting Node.js over the finish line first)
Does that... make sense?
Yes I think that (mostly) makes sense, thank you! My one clarifying question would be around:
if you want to use wasi:http in Rust, you do need to import it directly. jco knows how to provide that interface, so you'll generally be fine if you do that.
I am assuming that this means importing the wasmtime-wasi-http crate and using the functions from there to make my http calls? But I would not need to import the wasi:http wit definitions from https://github.com/WebAssembly/wasi-http unless I wanted to include those types in my component's public API?
Non-jco related sidenote: importing wasmtime-wasi-http to my project and building for wasm32-wasi causes several build failures via the wasmtime-fiber crate:
error: fibers are not supported on this platform
--> /Users/lnj/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmtime-fiber-16.0.0/src/lib.rs:17:9
|
17 | compile_error!("fibers are not supported on this platform");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0433]: failed to resolve: use of undeclared crate or module `imp`
--> /Users/lnj/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmtime-fiber-16.0.0/src/lib.rs:27:17
|
27 | Ok(Self(imp::FiberStack::new(size)?))
| ^^^ use of undeclared crate or module `imp`
wasmtime-wasi-http depends on wasmtime, so it will only build for the platforms wasmtime builds for
it is a host implementation of wasi-http
if you are trying to use wasi-http interfaces from webassembly, you should use wit-bindgen in your crate
with the wasi-http wits
Got this all figured out and documented in this repo. Thanks for all the help!
Funnily enough, I happen to be doing something similar and ended up with a codebase very similar to yours -- one thing I wanted to ask is how you built those generated typescript bindings? I used only incoming-handler so I just wrote the minimal required type declarations by hand.
I did a tiny bit of searching around jco and componentize-js underneath to see if there was something for that (generating type declarations) but didn't find anything.
Thankfully thats one of the easier steps, you can look through the build script in that repo's package.json for the full steps, but the gist of it is:
wasm-tools component new on that binary to get the component metadata in therejco via your package manager and run something along the lines of :npx jco transpile ./path/to/your/componentized/binary -o ./path/to/output --no-namespaced-exports
And it will output the typescript definitions. In my repo that is everything in this directory. Note that the --no-namespaced-exports flag is required because jco by default generates some code that is just barely not typescript compatible.
Thanks for the tips and spelling it out in detail, I'll see if I can work that into my flow!
@Landon James if I already have a 12_05 component, I should just be able to use this directly, yes? In other words, I should just be able to jco transpile and directly use it.
Oh hey @Landon James if you're interested in the code that I ended up with, it's up here after a bunch of polishing:
https://github.com/wasmCloud/wasmCloud/pull/1300/files
hopefully it's pretty easy to follow -- I ended up copying type definitions from jco explicitly, the ones in there are pretty complete so I didn't have to work too hard -- just some typescript type declaration wrangling
Ralph said:
Landon James if I already have a 12_05 component, I should just be able to use this directly, yes? In other words, I should just be able to jco transpile and directly use it.
Yep that is my understanding! jco makes it pretty easy to transpile the js bindings from any wasm (component) binary.
Last updated: Dec 06 2025 at 06:05 UTC