Stream: show and tell

Topic: Experimental basic-webserver on the new compiler


view this post on Zulip Johannes Rubenz (Jun 10 2026 at 15:11):

So, I wanted to try out Fable and thought a fun test would be a project I actually want to exist already: basic-webserver on the new Zig compiler. :sweat_smile:

Full disclosure: I know nothing about low-level programming – the AI did the heavy lifting and I steered (kind of), kind of like @nandi did a couple of weeks ago. So, please, forgive me!

I genuinely can't tell whether the result is useful or just well-organised slop. What I can tell is that it builds and the examples work, on macOS (ARM), against compiler commit 48b28c07:

demo-app.gif

demo-chat.gif

Check out the README for detailed info: https://github.com/studiorubenz/roc-experimental-basic-webserver-zig

It's also worth noting that, unlike the official ports, the host is written in Zig, not Rust.

I'll happily throw all of this away the day the official one lands; the ABI notes in the repo (IO-PORT-PLAN.md) might outlive the code.

Feedback very welcome – I'm especially interested in whether the Roc in the examples is idiomatic, or unidiomatic slop :grinning_face_with_smiling_eyes:.

view this post on Zulip Anton (Jun 10 2026 at 15:34):

Pretty cool Johannes, I did notice it tossed out a whole lot of tests and examples :p

view this post on Zulip Anton (Jun 10 2026 at 15:35):

Claude does this style often:

seed_64 = match Random.seed_u64!({}) {
        Ok(n) => n.to_str()
        Err(RandomErr(_)) => "(random error)"
    }

Using ? is a lot nicer.

view this post on Zulip Anton (Jun 10 2026 at 15:35):

Same here:

    path = "/tmp/roc-webserver-system-probe.txt"
    match File.write_utf8!(path, "round trip äöü") {
        Err(FileErr(_)) => "write_utf8 FAILED"
        Ok({}) =>
            match File.read_bytes!(path) {
                Err(FileErr(_)) => "read_bytes FAILED"
                Ok(bytes) =>
                    match File.write_bytes!(path, bytes.concat(" + bytes".to_utf8())) {
                        Err(FileErr(_)) => "write_bytes FAILED"
                        Ok({}) =>
                            match F

view this post on Zulip Johannes Rubenz (Jun 10 2026 at 15:41):

Thank you for your feedback on the AI-generated code, @Anton ! It's not something I take for granted, and I really appreciate it. I'll try to learn as much as I can from it. :slight_smile:

view this post on Zulip Anton (Jun 10 2026 at 15:43):

The mutex is a bit strange as well... not sure if that is necessary.

view this post on Zulip Anton (Jun 10 2026 at 15:44):

This file demonstrates ? nicely: https://github.com/roc-lang/basic-cli/blob/migrate-zig-compiler-edits/examples/command.roc

view this post on Zulip Anton (Jun 10 2026 at 15:47):

I also notice some differences in host.zig compared to Luke's platform like in rocReallocFn: https://github.com/lukewilliamboswell/roc-platform-template-zig/tree/5225da1582a17fcc36c9d00062adfc6659796bf2

view this post on Zulip Anton (Jun 10 2026 at 15:56):

I do like that open source gives people the possibility to take matters in their own hands :)
Porting basic-webserver properly is still a hard task for the best AI, but I imagine this could work perfectly satisfactorily in other scenarios. I hope it leads more companies to open source their app software so frustrated consumers can fix things :p

view this post on Zulip Anton (Jun 10 2026 at 15:57):

It's nice to know I can still do things fable can't :smile:

view this post on Zulip Luke Boswell (Jun 10 2026 at 20:59):

@Johannes Rubenz this is really cool. Id love to know how you got the platform started.. did you point Claude at an existing platform like my zig template or maybe the tests in roc repo, or use roc glue.

view this post on Zulip Johannes Rubenz (Jun 11 2026 at 06:33):

hey @Luke Boswell , I naively pointed Fable at the old rust compiler version and asked it to rewrite it for the new one in zig. Only after @Anton's kind feedback did I point it at your zig-platform-template and let it incorporate the ? error handling etc.

Zig and Rust are unfortunately out of my league... But what do you think of the machine-generated Roc code? I tried to enforce the new syntax and idiomatic style as much as possible... :sweat_smile:

view this post on Zulip Luke Boswell (Jun 11 2026 at 06:52):

imports the compiler's own builtins module directly

You should checkout the roc glue subcommand... it generates the interface and some nice idiomatic bindings for you (in C, Rust, or Zig)

view this post on Zulip Johannes Rubenz (Jun 11 2026 at 14:04):

@Luke Boswell :eyes: https://github.com/studiorubenz/roc-experimental-basic-webserver-zig#regenerating-glue

view this post on Zulip Luke Boswell (Jun 11 2026 at 20:19):

The app - host ABI is about to change dramatically so switching to glue will make the transition much easier. :grinning:

view this post on Zulip Johannes Rubenz (Jun 12 2026 at 05:18):

case in point: https://github.com/studiorubenz/roc-experimental-basic-webserver-zig/commits/main/ :slight_smile:

view this post on Zulip Luke Boswell (Jun 12 2026 at 05:19):

It's working for you? cool.

I'm just upgrading my template platforms now, hopefully I can cut a release

view this post on Zulip TeaDrinkingProgrammer (Jun 12 2026 at 06:46):

Ecosystem-wise, is Zig a better choice than Rust? I understand the compiler re-write, but I personally think that Rust is a better fit for host platforms, due to the ecosystem-size but there might be some advantages I don't know of.

Cool experiment in any case!

view this post on Zulip Luke Boswell (Jun 12 2026 at 08:03):

I think it's probably too early to fully understand the trade-offs between the two.

We haven't seen many production Roc platforms in the wild, Zig is also early-mid development as a language itself -- and most significantly our ABI or linking strategy between the app and platform host has been evolving as recently as yesterday.

What I have really liked about Zig is the tooling and control over low-level things. Authoring a platform (until recently with glue) has required pretty unique control over things like the symbols that end up in the pre-built host static library etc.

So I wouldn't be surprised if you were aiming to build a platform for industrial controllers you might choose Zig (or C), and if you were building an enterprise service with Roc scripting capabilities coordinating various effects you might choose Rust.

Not sure that helps at all?

view this post on Zulip Aurélien Geron (Jun 12 2026 at 09:34):

Isn't it possible to code a platform in any language you prefer, as long as it respects the C ABI? So the choice of language for the compiler doesn't affect the language used for the platform. I may be totally wrong, but that's what I thought.

view this post on Zulip Luke Boswell (Jun 12 2026 at 09:43):

Yeah I wont be surprised to see Kotlin, Swift, Go platforms popping up soon

view this post on Zulip Anton (Jun 12 2026 at 10:37):

When we still had the old compiler we did sometimes have problems getting Rust to do the specific linking we wanted but that may no longer be a problem.

view this post on Zulip Anton (Jun 12 2026 at 10:45):

But what do you think of the machine-generated Roc code? I tried to enforce the new syntax and idiomatic style as much as possible...

Nice improvements @Johannes Rubenz :)

Stdout.line!("ws: ${frame.message}")

You may want to use dbg here, those calls will get filtered out for optimized builds (or they will be very soon). Stdout printing can delay things a lot if you start doing benchmarks.

amp = replace_all(input, "&", "&")
lt = replace_all(amp, "<", "&lt;")
gt = replace_all(lt, ">", "&gt;")
quot = replace_all(gt, "\"", "&quot;"

You can chain these together with static dispatch for a cleaner look without intermediary variables. That also reduces the probability mistakes if you add lines later.

chat_page : Str
chat_page =
    \\<html lang="en">
    \\<head>

You may find it nicer to put this in a separate html file and use import as Str.

view this post on Zulip Johannes Rubenz (Jun 12 2026 at 11:40):

Wow, thanks @Anton for the feedback, which I've already incorporated and pushed upstream :check: ! I can actually use a lot of it for my Roc study plan as well, which is my primary goal at the moment.

(The plan spans 98 days (appropriately called "98 Days of Roc :rock:" :joy:) and is based on an AI-generated tutorial with 28 chapters. On top of that, I've built a validation pipeline that automatically checks every code example from the tutorial against the compiler, yolo! Now it's up to me to verify everything as I work through the tutorial and manually fix anything that sounds strange or seems wrong.)

That's also why I tried to get not only the basic web server working, but also basic CLI. And I "taught" my REPL to return type annotations. :laughing:

I'm having so much fun with all of this, and you, @Luke Boswell and the rest of the community are so supportive and motivating — thank you! :heart:

view this post on Zulip Richard Feldman (Jun 12 2026 at 18:18):

Anton said:

You may want to use dbg here, those calls will get filtered out for optimized builds (or they will be very soon)

more specifically, "very soon" will be once this PR lands :smile:


Last updated: Jun 16 2026 at 16:19 UTC