Hey there.
Just starting to play around with Roc.
It's great to see Webassembly support.
Is there already a good way to define WASM exports and imports?
is that the wasm/JS FFI? I think is is something that the host (so zig/rust/?) code would do
It's basically the equivalent of external function definitions or publically exported functions (on a linker level).
But they need to be defined in the compiled .wasm
file.
How does the Wasm compilation pipeline work?
Will both host code and the Roc code be compiled do Wasm and somehow combined?
yes
Is there an example for writing a custom platform in Rust?
The concept of Wasm imports/exports is not really visible inside Roc itself. Rather in the host language you define extern
s for whatever you expect to be "dynamically linked" with JS at runtime.
The examples
directory in the repo has several platforms in Rust.
in particular https://github.com/roc-lang/roc/tree/main/examples/platform-switching/rust-platform
which passes a string between the roc and rust code
and https://github.com/roc-lang/roc/tree/main/examples/interactive/cli-platform which does a lot more
One of the examples there is a WebAssembly platform and there's an HTML page to run it in, but the host is in Zig rather than Rust.
https://github.com/roc-lang/roc/blob/main/examples/false-interpreter/platform/src/lib.rs is perhaps a good intermediate rust platform
Yeah, I sort of got that.
So I would have to:
For imports:
For exports:
main
Right?
The false interpreter doesn't compile to wasm currently though. One of the Rust crates doesn't support that target.
we're also working on (more) codegen to make passing stuff across the boundary easier, and making all of the manual weird function signatures go away
PS: is there a WASI platform yet?
If not I could look into contributing that.
I'm not sure your description of exports is right... are you referring to guest as Roc code or JS code?
I would imagine Roc
But then that's not a Wasm export because both Roc and Rust compile to wasm
So you have two boundaries here. There's the Roc app/host boundary and then within the host there's a Rust/JS boundary.
Well, I would need to have a Webassembly exported function that then calls into Roc code.
But I think with the examples I have enough to work something out.
theduke said:
Well, I would need to have a Webassembly exported function that then calls into Roc code.
I don't quite follow what you mean here.
Hmm.. maybe this is a good way to say it: From Rust's point of view, JS code and Roc code are both "extern C".
Also worth noting that the Roc app and host end up as a single Wasm module, not two separate ones.
From Rust's point of view, JS code and Roc code are both "extern C".
Ah, I see.
#[link_name = "roc__mainForHost_1_exposed_generic"]
fn roc_main(_: &mut RocStr);
So Roc exports are also just extern fns.
That makes it easy then to forward those as Wasm-level exports.
Right yeah I suppose so!
Is there some concept in place or plans around creating alignment between platforms?
Or make code run on multiple platforms?
Easy example: file handles
Would be very awkward to duplicate code that works with files between WASI and eg the standard CLI.
The same Roc platform can compile to many targets.
So you can write a Rust platform that supports a WASI target and a Linux target and a Windows target.
Currently we don't have one of those though
Just linking this in case it is useful as a reference: https://github.com/bhansconnect/functional-mos6502-web-performance/tree/master/implementations/roc-effectful
This is an emulator for a cpu in Roc that run in the browser using wasm. It is pretty simple, but it shows a full js platform with wasm app. That being said, there is a decent chance the roc is outdated and needs to be update some if you were to directly copy from it.
Uh, I just saw wasm3
is a dependency.
Is that somehow for the repl?
Or maybe just for tests?
just for tests right now I believe
repl is planned
Last updated: Jul 06 2025 at 12:14 UTC