Stream: beginners

Topic: Hook for hot reload


view this post on Zulip Jasper Woudenberg (Sep 09 2026 at 09:35):

Is there some kind of hook I can define in the host that Roc will call after doing a hot reload?

My use case: for my static site generator Jay I let the user define in Roc code pipelines. For example, the user might specify that files matching the pattern posts/*.md should be processed by converting the markdown to html.

When running this Roc code Jay will start a development serving, watching for changes in those markdown files and serving the site on localhost. It's awesome that the Roc runtime watches changes in Roc source files itself. What I'd need is a way for the host to know when pipelines might have changed. That way I can push an update down to any clients currently connected to the development http server.

view this post on Zulip Jasper Woudenberg (Sep 09 2026 at 09:41):

A related but different request, and maybe a bit spicier then the previous one: it would be really awesome if the platform could also get compiler warnings and errors. That way Jay can render them in the browser where the site preview is shown.

Why this matters: if brings down the amount of windows people need from three to two, which I think is a significant improvement in UX. Imagine someone developing a static site using Jay (or another static site generator). You need three windows open:

  1. Your editor, in which you're making changes to source files of the site
  2. Your browser, showing you result of the changes you're making to the site (happy output)
  3. A terminal, showing compilation warnings and errors (sad output)

The final two windows both show "outputs" of the first one. If those can be shown in a single window I think it improves the experience a lot: Two windows can often be fit side-by-side on a single monitor, but not three.

view this post on Zulip Jasper Woudenberg (Sep 09 2026 at 09:49):

Writing all this down is giving me extra thoughts: The compiler errors and warnings would be great to have, but not just on code changes, also on the initial compilation result that starts the platform.

I believe the goal is for Roc to never block, so the platform already runs regardless of whether there are warnings or errors.

Maybe there could be some function the host can defined that gets called with warnings/errors for every compilation, including the first one. The host should be implemented in such a way that it does not call platform functions before the first call to this hook, but it can do other setup work in that time. For instance, Jay could start the webserver and scan the project directory for source files (like markdown files). That way setup work on the host and Roc compilation can happen in parallel.

view this post on Zulip Anton (Sep 09 2026 at 13:01):

it would be really awesome if the platform could also get compiler warnings and errors. That way Jay can render them in the browser where the site preview is shown.

Maybe there could be some function the host can defined that gets called with warnings/errors for every compilation

Do you see any problems with this @Richard Feldman?

view this post on Zulip Anton (Sep 09 2026 at 13:10):

Is there some kind of hook I can define in the host that Roc will call after doing a hot reload?

Not yet, but I do see value in it.

view this post on Zulip Richard Feldman (Sep 09 2026 at 14:32):

I might be misunderstanding, but for the original use case can't the platform already take care of that? As in, the platform already receives "posts/*.md" so it knows what to watch, and it also controls the development http server, so couldn't it watch those files and then send updates to the server? :thinking:

view this post on Zulip Richard Feldman (Sep 09 2026 at 14:32):

the "display errors in the platform" idea is cool! I'd say start a separate #ideas thread for that so we can discuss :smile:

view this post on Zulip Jasper Woudenberg (Sep 09 2026 at 17:02):

Richard Feldman said:

I might be misunderstanding, but for the original use case can't the platform already take care of that? As in, the platform already receives "posts/*.md" so it knows what to watch, and it also controls the development http server, so couldn't it watch those files and then send updates to the server? :thinking:

Yes, I don't need any help with this part!

So there's two types of files to watch in the case of Jay: (A) the source files of the site (markdown files, assets, whatever else) and (B) .roc file(s) containing the build pipelines turning source files into output files.

For (A) Jay will watch the filesystem and process changed files by passing them to Roc code.

But if the .roc file(s) changes I will need to reprocess source files as well, because a change in Roc code will typically affect how input files are processed into output files.

For that reason I need a heads-up in the host that Roc code has changed, which Jay will handle by reprocessing "active" files (those being browsed currently) using the updated Roc pipeline.

view this post on Zulip Richard Feldman (Sep 09 2026 at 19:06):

ahhh I see

view this post on Zulip Richard Feldman (Sep 09 2026 at 19:09):

yeah these both seem interesting, although I think at this point they're things to revisit post-0.1.0 :smile:

view this post on Zulip Richard Feldman (Sep 09 2026 at 19:10):

I wouldn't go as far as to say we're at a feature freeze for 0.1.0 but I do want to avoid taking on significant new projects, given that we already have enough in the backlog

view this post on Zulip Jasper Woudenberg (Sep 09 2026 at 19:52):

:thumbs_up: totally makes sense!

view this post on Zulip Scott Campbell (Sep 17 2026 at 07:22):

The dev server could take responsibility of watching the *.roc files, orchestrating compilation & reload events too?

Then expose/call a file changed / pre-compile hook function / event.

And then run the roc build ./main.roc process, and capture the exit code & stdout/error.

Then expose/call a post-compile / pre-reload hook function / event.

Reload any parts as needed & capture and reload state as necessary.

Then expose/call another post-reload hook function / event.

Or something like that.

Personally, I was writing a complete hybrid zig/roc SPA hotreload dev stack... cli tool, dev server, server platform, server app, client platform, client app... that also rebuilt the zig platform host and roc app as necessary... (the plan was for app authors to also vendor & own the underlying the zig platform, and make changes as necessary for their requirements)

But soon abandoned that project, so it's half implemented and a bit of a mess, which i started at the early days of the roc zig rewrite but was running into documentation difficulties with the ABI/glue so i decided to pause the project.

Ohhh... yeah that was right... i wanted to pass a roc function from roc to zig, and then have zig supply the argument data and call the function. But then i realised i didn't have to... can can implement, the same way joy does it. And I was also getting segfaults when trying to have more threads... 1 for file watcher, and 1 for... http server... i think it was... but i figured can just do both on the same thread as a workaround.

And I was also replacing and removing all dependencies, the zig std library http webserver, with my own implementation. And the file watcher library that I was using, with my own implementation etc.

And joy (https://github.com/niclas-ahden/joy), was implemented in rust against the roc alpha4 compiler... but it seems development has been ported to roc pre-0.1.0 compiler and continued development.

So yeah... if joy doesn't continue to solve the "amazing all-in-one SPA web dev platform", I'll probably pick this project up again and try again, should i need a SPA platform.

And at the moment, the server can actually ONLY handle static content... due to the function call design limitation that i was hitting earlier, despite wanting full dynamic SPA with live websockets, hotreloading & error forwarding and such.

Example (see the README.md):
https://github.com/scottc/rig

Cli command:
https://github.com/scottc/rig/blob/master/src/dev.zig

Dev server:
https://github.com/scottc/rig/blob/master/templates/default/platform/dev_server.zig

File Watcher:
https://github.com/scottc/rig/blob/master/templates/default/platform/watcher.zig

Http server (commented out, was reimplementing...):
https://github.com/scottc/rig/blob/master/templates/default/platform/server.zig
https://github.com/scottc/rig/blob/master/templates/default/platform/rig-server.zig
I forgot which one...
https://github.com/scottc/rig/blob/master/templates/default/platform/host.zig

Placeholder client (Javascript, to be replaced with roc-wasm):
https://github.com/scottc/rig/blob/master/templates/default/public/index.html

I don't imagine the performance costs would be too severe, that it would block the DX feature, roc does some caching for incremental builds... I think less then 1 second would be tolerable?

And deal with the performance overhead of de/initializing a roc process over and over again later (it would need to pull from cache/disk & allocate memory).

Worst case, could statically/dynamically link or vendor the entire roc compiler and keep it in the dev server memory, and dig into the roc compiler internals if necessary... but imo, that's a post 1.0.0 release feature.

view this post on Zulip Jasper Woudenberg (Sep 17 2026 at 16:47):

Yeah, I was considering letting the platform run roc build itself when it notices a change in .roc files in the version of Jay I wrote for the previous version of the compiler. It's slower, I'd have to transfer state to the new process, the web-server would need to be restarted in the new process (possibly resulting in a disconnect for a short period of time), you'd need to reimplement Roc module-dependency walking to know when to rebuild.


Last updated: Sep 24 2026 at 15:59 UTC