Hello everyone, great to be here. Trying to understand how Roc works with platforms and I'm pretty excited about the possibility of writing my own platform specifically with Zig.
Is there any documentation on how to do this?
Reading through some existing platforms, I see that there's some boilerplate around malloc and free, but I'm most confused about
Hi @Stephen :)
Is there any documentation on how to do this?
No, we're making big changes in how platforms work so we delayed writing docs for it.
This is a recent example of how you can set up a zig platform so I recommended looking at that for guidance.
- How the glue works
Glue code allows the Roc program to talk with the platform written in Rust, Zig...
Automatic generation of Glue code (WIP) is currently only available for Rust.
- How to export functions from the platform for use in the application
Example of the Zig part.
Corresponding Roc part
- What can the Roc program provide to the host platform (mainForHost?)
Anything your heart desires :)
I wrote this article https://lukewilliamboswell.github.io/roc-ray-experiment/ to capture some of the lessons I've learnt about platform development. Writing platforms in Zig is super fun, let me know if you have any questions.
Thank you @Anton and @Luke Boswell
I'll take a look at these :pray:
If I want to implement a Rust platform, how do I get started?
Albert said:
If I want to implement a Rust platform, how do I get started?
All messages from this thread so far do apply to Rust as well.
Additionally, you might be interested in the second talk by @Luke Boswell from last month's meetup.
I also have a template repository for rust which has most of the parts ready to go
https://github.com/lukewilliamboswell/roc-platform-template-rust
Just watched the vid. So now I understand that Roc cli/compiler has 2 jobs.
which is exactly the opposite of Deno/Browser that takes JavaScript as data and run it in memory.
when the host code interacts with roc app code, the source is long gone
It's more like a FFI
so I am writing a new kind of communication software (chat + social media) that is decentralized (meaning local-first, client-first, not blockchain)
the protocol is https://nostr.com/
my software is https://blowater.app/
However, after 1.5 years of work, I have realized that the Browser platform is fundementally not friendly to local-first software
The JavaScript language is also just not a good language to implement super robust software (the client needs to handle 2GB+ data locally)
Roc looks like a super good fit for my project because
So, I want to implement a platform that's basically like a Browser, but using Roc for scripting, providing modern network & storage APIs
along with a GUI layer
It's not a hobbyst project, I am very serious with real budget behind it
But, I don't understand Rust nor Zig enough to get started, even if @Luke Boswell 's template. I need more help.
For example
image.png
Now I know that let out = call_the_closure(buffer);
will run the Roc code.
But I don't understand
I have been following Roc for 2 years and have watched @Richard Feldman 's talks since the Elm days btw. Now Roc feels like mature enough, at least for me, to work on.
As for the GUI layer, I am thinking about something like Egui or the GPUI from Zed editor. GPUI uses Egui as well. Just need to figure out what's the best API for Roc to consume.
Egui can run on Android now, so if we can implement a Rust Egui platform for Roc, maybe Roc can run on Android as well. iOS is always another beast.
But, if we can achieve it, it's 100X better than Flutter which is a good platform with a horrible language. Dart is the worst part of Flutter in my opinion.
If this is possible and exciting to you, please let me know. I need help to get started.
I've been very motivated by the idea of a GUI platform for roc. I've done a few experiments over the last couple of years to learn more about platform development and generally explore the space. I think it'd be super cool if we had a decent GUI platform. Roc is 100% a great fit for this in my opinion.
You may find Richard's Action-State design proposal an interesting read. It's a design for how GUIs might work in Roc (necessarily different from Elm).
I've built a PoC using raylib lukewilliamboswell/roc-ray. That platform works well and there is nothing really stopping it today from being a great graphics platform. It just needs some polish, more API coverage, an upgrade to a later zig version and a release. For the GUI parts, unfortunately we would need a pure roc layout implementation, something like flutter's layout algorithm would be good I think. Thought raylib is definitely not aimed at making modern/pretty looking GUI's.
The project I have been watching closely and think will be most suitable is linebender/xilem which brings together a lot of the GUI efforts from across the Rust ecosystem. They recently launched at RustNL, and there has been a lot of active development since then. I haven't had a chance to experiment with it (works been busy lately). I started early with this https://github.com/lukewilliamboswell/roc-masonry-experiment and my plan was to upgrade that to xilem and generally clean it up -- similar to how I've cleaned up the rust template (which has the latest and greatest).
One potential issue is that glue gen is still a WIP and needs to mature more. Writing types for interfacing between Roc and Rust by hand is the most reliable method, but also can be tedious. I started on https://github.com/lukewilliamboswell/roc-glue-code-gen with the goal to work on glue, but that turned into making template repositories. Actually fixing the glue generation requires a level of rust knowledge that I don't have right now.
Bit of a random collection of thoughts, but hope that helps.
Is glue compiled to the host or to the app binary?
or the GUI parts, unfortunately we would need a pure roc layout implementation, something like flutter's layout algorithm would be good I think.
Why? Is it because this approach is more cross platform? So that the host just take the pixel computed by the Roc GUI lib and draw it?
https://opensats.org/blog/opensats-receives-additional-funding-of-dollar21m-from-startsmall
Jack Dorsey is bootstrapping the Nostr ecosystem with additional 5M donations, on top of 5M last year.
There is real needs to implement a simpler, safer hosting environment for micro apps
Is there a plan for helping people manage public/private keys? That sounds like a challenge for new users. Or is the idea generally that identity will be more temporary.
Currently, with Browser apps, the private key is either stored by an extension or by the app itself which are not safe in both ways
In mobile and desktop, keys are stored by the apps
So, if you use the same key on many apps, you increase the danger of a key exposure
It's not like a blockchain that if you expose your key, you just transfer your fund as quick as possible to a new key
It's social media, if you expose your key, your identity is compromised forever
The user can generate a new key and start fresh but all the historical data is now accessible by the theft
With a Roc platform, I can minimize the attack surface
Albert said:
Is glue compiled to the host or to the app binary?
Glue is a feature of the roc cli that provides all of the Roc types for a given platform. So we can write plugins that code gen the equivalent host code to interface with the platform. I.e. have a glue plugin that will code generate rust code implmentation for that specific platform.
But it's a WIP and generally not very mature right now.
Luke Boswell said:
Albert said:
Is glue compiled to the host or to the app binary?
Glue is a feature of the roc cli that provides all of the Roc types for a given platform. So we can write plugins that code gen the equivalent host code to interface with the platform. I.e. have a glue plugin that will code generate rust code implmentation for that specific platform.
But it's a WIP and generally not very mature right now.
I still don't get it but I will learn more LOL
Albert said:
With a Roc platform, I can minimize the attack surface
Having key management built-in to the platform is separated from a GUI platform
Having a GUI platform is the 1st step, then I can import the GUI platform as a library and build key management on top of it
It's like Ark forks Chromium
However, I am not sure if I should choose Rust or Zig
Rust should be safer to write considering that this platform will load arbitrary Roc code
The use case is to dynamically load remote Roc code instead of compiling into the same binary
Similar to @Richard Feldman 's idea of writing editor extensions in Roc
If we do a good job, we can support both compilation mode (like electron) and dynamic mode (like browser)
Then we can get rid of both React Native and Flutter
Another approach is to write native apps using SwiftUI, or Kotlin and then use roc as a plugin. Using the same API would mean the roc parts can be identical, and defer mobile platform specific things to the platform.
Developing the platform in a mature ecosystem like Swift will be a nice experience. I've got a template platform for Swift and it works nicely.
Luke Boswell said:
Another approach is to write native apps using SwiftUI, or Kotlin and then use roc as a plugin. Using the same API would mean the roc parts can be identical, and defer mobile platform specific things to the platform.
If I can keep 90%+ of my code in Roc and just interfacing Kotlin or Swift platforms, that's also good
I am not familiar with mobile so desktop platforms will be my 1st target. I need
so, maybe I can start to add websocket to the CLI platform to learn
@Richard Feldman said there was no cross-platform Roc app. Can I interpret it as that if I want cross platform Roc. I can wirte the shared part as a Roc library and 2 separate Roc app that interface the platform IO and just import the Roc library?
This design force the coder to push IO/Side Effects to the most outside of the system
What about async code? Can I have async code in a Roc library because it's an effect?
If your interested in how cross-platform could work, and looking for a larger and more mature example, checkout imclerran/roc-start. That's a nicely written roc app that runs on all of the targets supported by basic-cli, so currently linux/macos OS and x64/arm64 ARCH. The basic-cli platform provides pre-built binaries for various OS/ARCHs so the same roc app can run on all of those without needing to change anything. Indeed, it's easy to cross-compile from a macos to build a binary for linux using just the roc cli.
E.g roc build --target=linux-x86 src/main.roc
What about async code? Can I have async code in a Roc library because it's an effect?
Others are welcome to correct me, but I believe that will be possible once Task is a builtin. :thinking: What are the blockers on that? I could not find a tracking issue.
Not just task as a built-in, needs the full effect interpreters setup.
Theoretically it could be manually done today (I did it with some future testing, but it is not a nice experience)
A few random other answers:
Brendan Hansknecht said:
A few random other answers:
- A platform has roc code in it cause it needs to define the API between roc and the underly language. It also is allowed to define arbitrary roc libraries.
- Pure roc layout logic is not required for any of this. Might be nice to have, but layout logic can be manually done or dealt with in the platform. Doing it purely in roc could help with consistency across devices. This is especially true if building multiple device specific platforms.
- While this project could probably be forced in current day roc, I honestly believe we are early for this project. That said, if you are willing to force it, or will to also help contribute to fixes in the compiler you need, definitely in the realm of doable.
- Glue generates code in the host language that helps deal with ffi from the host to the app.
I guess I should just start with adding some dumb APIs to the Rust template and get a feel with Roc
Yeah..or as you said, add websockets to basic cli
What is a effect interpreter
?
This syntax module [line, Err]
is not described in https://www.roc-lang.org/tutorial#modules
That's the difference between module [name]
, exposes [name]
and exposing [name]
?
That syntax is just a regular module https://www.roc-lang.org/tutorial#regular-modules
Unfortunately that part of the tutorial needs some love :sad:
An effect interpreter is a large upgrade to roc that has been in development for some time. It will change the way the host in the platform is written and enable fully async execution of effects.
Luke Boswell said:
Unfortunately that part of the tutorial needs some love :sad:
LOL
Luke Boswell said:
An effect interpreter is a large upgrade to roc that has been in development for some time. It will change the way the host in the platform is written and enable fully async execution of effects.
Is this related to that host API implementations are not async at the moment?
For example, I am looking at the http request implementation of basic cli
Is host API execution blocking at the moment?
Is there an article or design draft of effect interpreter that I can read?
image.png
Is this code also the code used in the Roc compiler or written only for platform development purpose?
Mostly for platform development, but the roc compiler uses it in some places
And yeah, lack of effect interpreters is why every effect is synchronous currently
Is parallelism also the decision of the platform?
Yes
For example, basic webserver is automatically multi threaded, but gives the requests no control over concurrency.
Long term, it will likely support better async effects, but it might never support spawning arbitrary threads
Basic CLI on the other hand is single threaded by default but plans to support spawning tasks that can run in parallel (multi threaded communication architecture unclear at the moment)
Is there an article or design draft of effect interpreter that I can read?
Do we have a google doc for this @Richard Feldman?
hm I don’t think so!
You would really think after all of this discussion in various threads that we would have something written up.
I guess the only write up is the small summary here: https://www.roc-lang.org/plans
The name "interpreter" does not convey what it does under the hood
It is essentially a standard async state machine. The reason for the word "interpreter" is that the platform is essentially implementing an interpreter to run the state machine that executes roc code and effects.
What is the Rust representation of a Roc record in the basic-cli?
If you have the following Roc record
MyRecord : {
age: I64,
name: Str,
}
In rust this would be
#[repr(C)]
struct MyRecord {
age: i64,
name: roc_std::RocStr,
}
fields are sorted alphabetically
So I simply return a RocResult<MyRecord, RocError>
in the rust platform lib?
I'm not sure what you are doing, but that looks ok to me.
I think, that the fields are not only sorted alphabetically, but also be size in memory. If I am correct, then "name" will be before "age".
Luke Boswell said:
I'm not sure what you are doing, but that looks ok to me.
I am trying to expand the file API of the basic cli to return metadata of the file as well
It can be a useful small tool to check duplicated files
They are sorted by alignment and name.
age
-> i64
, aligned to 8 bytes
name
-> Str
, aligned to 8 bytes as well (cause it is a pointer and 2 i64
s)
So should be age
then name
.
Do we have a file people can check to find the alignment for a type?
Last updated: Jul 05 2025 at 12:14 UTC