How do you build a hello world to compile to wasi?
I've compiled the wasm example but that requires a JS host.
2 messages were moved here from #beginners > syntax: whitespace vs comma for items by Brendan Hansknecht.
To my understanding, wasi would use something like a zig host that contains a main with a roc platform. I think we support it, but I have not messed with that pipeline in a long time.
In the worst case, you can just compile the roc code with --no-link
and targeting wasm. Then have a platform built for wasi link against that.
As a clarifying note, all roc code is totally agnostic of that information. Whether it is for the browser or wasi roc will generate the exact same thing. It is up to some sort of host to deal with mapping browser/wasi primitives to roc io primitives.
I have played around with wasi some time ago. I did not go far, but the hello world example worked.
I pushed the code here: https://github.com/ostcar/roc-wasi-platform
It is its own platform, written in zig. Currently, it only knows the Task writeLine
. My goal was to support all wasi functions. But I lost the motivation :)
ah ok, this is my confusion then
wasi requires a bunch of bindings. I wasn't sure if that was built-in to Roc or not
So it sounds like someone needs to build that via a runtime. And Oskar has started that. Very cool
Yeah, Roc has no io primitives and depends on a platform for them. More context here: roc-lang.org/platforms
@Oskar Hahn doesn't wasi expect a "wasi_snapshot_preview1" imported value from the host? I don't see that in your host.zig
It is very easy to build this in zig. Zig has build an abstraction layer around wasi, so you can use the normal zig functions.
For example, the writeLine
Task is just:
export fn roc_fx_stdoutLine(str: *RocStr) void {
const stdout = io.getStdOut().writer();
stdout.print("{s}\n", .{str.*.asSlice()}) catch unreachable;
}
There is nothing wasi specific about it.
I wonder if we could just compile the rust basic cli for wasi?
ok, so I'm trying to understand how things are linked here.
Doesn't wasi have some sort of concept for logging? And if so, how does roc_fx_stdoutLine
get linked to that?
I was expecting to see some sort of mapping from "wasi method" to the implementation method roc_fx_stdoutLine but i don't see any such thing.
I will of course pull down your project and try it out :)
It does indeed work! I'm going to play around with this some more.
@Brian Carroll might have some more info on this!
Well in terms of what to do, Oskar has covered it.
I think there's a misunderstanding about how the various layers fit together.
@Matthew Phillips you actually wouldn't see names of WASI methods at the source code level unless you looked inside libc implementation code or something.
So in the Zig code above, stdout.print
will compile to different things on different targets.
If you compile for Windows then there will be some Windows API call in there.
If you compile for a Unix system there will be syscalls like write
or something.
And if you compile that same Zig code for WASI then it will compile to WASI's version of write
. I can't remember what it's called.
Roc has no concept of Windows syscalls or Linux syscalls or WASI syscalls.
Those things are dealt with by the compiler of the host language.
Also WASI does not directly have a concept of "logging" really. It's a POSIX-like system interface, so it has a concept of stdout, and it has a concept of writing to files, and you can use those for logging if you want.
Ah ok, so in this case there's no connection because WASI doesn't have a concept of logging
But it does have one of filesystem access presumably
So somehow there needs to a connection between the platform's "readFile" method and the WASI "readFile" method
The platform being the roc platform, i mean
Or wait
Matthew Phillips said:
But it does have one of filesystem access presumably
Yes it has the same concepts as Unix or Linux has. It's an interface layer to the OS. It has the same concepts as any OS.
OK, maybe I get it now
So, in the host.zig you would call zig's "readFile" method, and that thing, under the hood, connects to WASI's readFile method
yep
Ok, then as far as the connection between the Roc code and the host.zig
, I see roc_fx_stdoutLine
as a Zig method. I assume that this is some sort of method naming convention that causes the connection?
yes, the roc_fx_
prefix
roc_
probably always in front, then fx_
because that's the exported module in the main.roc
fx is short for "effects"
Oh, so roc_fx_
is always the name? It's not because this module happens to export something "as Fx"?
If I changed that to as Something
then it doesn't because roc_something_
It expects to be an Effects
Oh wow OK if we're digging in this deep I'd have to look it up, I dunno
Not important :)
I know enough to know what to do to add a new method, so this has been a lot of help, thanks!
Name comes from here: https://github.com/ostcar/roc-wasi-platform/blob/1796542883803f9a573e1b29f89d0348e1e4d617/src/Effect.roc#L14
Always prefixed with roc_fx_
as Fx
from: https://github.com/ostcar/roc-wasi-platform/blob/1796542883803f9a573e1b29f89d0348e1e4d617/src/main.roc#L10
is used for other generation.
So you mean, the roc_fx_
prefix is defined somewhere in the Roc compiler and not in the platform's code, right?
Not important that I understand this part just yet :) I'm unblocked to experiment.
the
roc_fx_
prefix is defined somewhere in the Roc compiler and not in the platform's code, right?
yep
Oh neat @Oskar Hahn, I was thinking about starting one of these.
It would be awesome to write up a zig glue spec which would make zig platforms so much quicker to write.
Definitely an after AoC project I'm keen to look at.
AoC?
Advent of Code
to write up a zig glue spec
I have been debating doing this for a long time. I think zig would be the easiest language to build a nice spec for. comptime
will make a lot of it super easy. c++
would also be pretty easy, but probably messier than zig due to more complex templates and some other struggles. c
you have to use macros and repeated imports or way more code gen to get all of the types and it is much more painful.
This would be really amazing :)
I have been debating doing this for a long time.
That said, my list of things to look at or work on is quite large rn.
If I understand, it would be a single implementation of the IO methods that you could then use in any platform, right?
the zig glue spec?
Yeah
Like, it would be nice if there was a library that implemented readFile, other IO methods, and then you could use that library in a platform that compiles to WASI, and in a platform that compiles to native, etc.
So that the platforms don't all have to implement those themselves.
So zig glue spec is different. It is about automatically generating zig code that interacts with roc. That way you don't need to know roc internal details to write a zig platform. Instead, that will all be automatically generated. For example, all the code here was auto generated by the rust glue: https://github.com/roc-lang/basic-webserver/tree/main/platform/src/glue
That said, someone could totally make a zig library for implementing a number of common primitives that would then be shared between many platforms (like readFile).
That said, it would be up to each platform as to whether or not they support a readFile primitive. It may make sense for a cli platform to have read file, but it probably doesn't make sense for frontend webpage platform.
@Matthew Phillips you're going to love the Module Params design. I just added a link on https://github.com/lukewilliamboswell/roc-awesome It's a longer read, and I think Agus has just started on parts of it. But yeah, platform independent libraries will be great!
Brendan Hansknecht said:
That said, it would be up to each platform as to whether or not they support a readFile primitive. It may make sense for a cli platform to have read file, but it probably doesn't make sense for frontend webpage platform.
yep, agree!
Luke Boswell said:
Matthew Phillips you're going to love the Module Params design. I just added a link on https://github.com/lukewilliamboswell/roc-awesome It's a longer read, and I think Agus has just started on parts of it. But yeah, platform independent libraries will be great!
I don't know Roc well enough yet to fully get it, but in general this makes me very happy :) Going to pour over the proposal some more
I think for platforms, they will just expose low level primitive IO like TCP/IP or Streams etc and then the package/library ecosystem takes thing from there. With all modules being platform independent by design, this makes it really easy to share things across platforms that have similar functionality. E.g. any platform that has TCP/IP can use Agu's roc-pg to work with PostgreSQL servers etc
Last updated: Jul 05 2025 at 12:14 UTC