Anton, Luke and Richard, I'm curious on your thoughts and experience with the Rust to Zig rewrite now that the beta release is almost here. Mainly wondering if you've run into similar issues that Bun has had with Zig. Have you run into any memory safety issues like heap-use-after-free or memory leak?
https://www.youtube.com/watch?v=NgUNjjV_AkY
Only reason I'm asking is to ask did rewriting in Zig make things better overall and is the "sunk cost fallacy" being avoided?
As far as memory safety issues go -- my experience with Zig has been really great.
I think the new compiler has only had like two really minor bugs in the whole time. The Zig tooling is solid and it makes doing exotic things with low-level memory really easy.
My favourite thing has been building out heaps of test infrastructure to aggressively check for issues. Like building platform hosts which track every single allocation a Roc app makes and throws an error if anything doesn't balance. You could do this in Rust too I'm sure, but Zig's allocator patterns fit nicely.
And the performace goals of Roc required unsafe rust which as I've heard is much less nice of an experience than zig, which has in mind that you're going to do unsafe things and doesn't say "you've brought it on yourself, you're on your own there". I would expect bun to slow down after the rewrite, provided they don't use much unsafe rust
Yeah, I was thinking the same thing. They got all their tests passing in Rust, but how much optimizations and unsafe code will be needed to be as fast as their Zig code base.
They did do a big anthropic marketing writeup on the process where they're claiming better on every metric but they're doing it by implementing stuff on top of the port.
@Brian Teague I just posted a write-up about this! https://rtfeldman.com/rust-to-zig
Richard Feldman said:
Brian Teague I just posted a write-up about this! https://rtfeldman.com/rust-to-zig
Nice! In the post you ask if people want more posts, yes I do.
Also, I found at least one todo link: https://rtfeldman.com/rust-to-zig#:~:text=Zig%27s%20compiler%20itself%20is%20another%2E points to https://rtfeldman.com/todo/link/to/this
Richard Feldman said:
Brian Teague I just posted a write-up about this! https://rtfeldman.com/rust-to-zig
I somehow completely missed the hot reloading... when did that land?? (PR) (And how does it work?). Can't find history on zulip about it yet. Also another vote for more posts about zero allocations etc.
@Jonathan it's magic :grinning_face_with_smiling_eyes:
Also, I'd like to know how it works too :plus: :one:
I think I have a rough idea but there's some cool tricks in there I'm sure.
At a high level all the magic is in https://github.com/roc-lang/roc/blob/main/src/machine_code_shim/main.zig
For dev runs like roc app.roc -- we actually link the prebuilt-host with a shim and keep that in cache, so when you first run a roc app using a platform, it links but subsequent runs (of different apps -- including hot-reloads) re-use that same executable.
But how can this work? the magic is that Roc lowers the app to machine code (or just the LIR for the interpreter shim) -- and then passes that via shared memory.
So as far as the platform host is concerned it's just calling into Roc's entrypoints (like main_for_host! and it has no idea it's actually linked with a shim into some special harness that defers the app parts until runtime and coordinates with the roc cli.
I hope I didn't butcher that explanation...
I think a key aspect of this to work is that the "roc app" is just lowered to pure functions and there is no statefulness -- the host is responsible for the runtime and managing state between calls into Roc.
yeah pretty much! there's probably a blog post in there somewhere too, but I just got done with this one :joy:
But you still have statefulness in what is passed back through the game loop. Say that after saving, in the next iteration of the cave climb loop, you are also tracking hunger, or you change how health is represented from a U8 to a tag union. You can't automatically transfer over that without an explicit migration function, no? I guess you can't change anything that affects the platform boundary?
Or if you had a thin platform and the game loop lived in Roc recursively or via while loop, you'd have the same problem too?
yeah if you change certain types we can't hot load - I implemented some basic "report an error" in some of those scenarios but as I recall I don't think I covered all the cases yet :smile:
I don't think having a migration system makes sense unless there's some concrete demand for doing this in production; since it's just for dev at the moment, I think the important thing is that we inform you when we weren't able to hot load so you're not wasting time
and then you can restart it etc.
Richard Feldman said:
I don't think having a migration system makes sense unless there's some concrete demand for doing this in production; since it's just for dev at the moment, I think the important thing is that we inform you when we weren't able to hot load so you're not wasting time
Oh agreed. I was thinking in comparison to BEAM systems where - if you want to even do that kind of thing for the uptime - it's supported with a code_change callback. But yeh, different goals entirely than for dev ux.
Have you thought about adding a blog section to roc-lang.org to share this same information? This is one of your best articles I've read, and would be extremely insightful to people coming to the website for the first time.
if you're interested in a post on the technical details of how we used the new compiler's compile-time execution of pure functions to get HTTP request routing down to zero allocations, let me know
I am always interested on the internal workings of the Roc compiler.
but our closure captures don't heap-allocate because Roc is the first non-academic language to implement polymorphic defunctionalization through lambda set specialization
Can I get this on a t-shirt :joy:?
Are you still using ReleaseSafe when running the test suite for the compiler to catch memory safety bugs before releasing nightly with ReleaseFast to the public? Also curious if you measure code coverage % when running the test suite.
@Brian Teague you're in luck! head over to the roc :rock_on: merch store any you can pick one of these bad boys up! All the cool kids are wearing them.
![]()
Tbh would probably buy this
Are you still using ReleaseSafe when running the test suite for the compiler to catch memory safety bugs before releasing nightly with ReleaseFast to the public?
CI tests get run in .Debug mode which uses the same safety checks as ReleaseSafe.
Also curious if you measure code coverage % when running the test suite.
We do, I will check what it's at right now.
I can't easily check on macOS, and I don't have time to explore alternative routes in the foreseeable future.
Last updated: Jul 23 2026 at 13:15 UTC