Auto reload WASM with zig+lume
I’ve been taking some time off to rest and recover from health issues that made it hard to focus. To ease back in, I’ve started a small project: shine
The project would do well to be multiplatform - mobile and web. The obvious choice was flutter and I have enjoyed working with it before.
However, as I’m currently in love with zig , I wanted to work with that instead.
Libraries
Graphics
I’ve been playing with raylib and that was my initial instinct. However, raylib does not support iOs and has issues with wasm
I considered a few options, including
- sdl , which looked great but was perhaps a little too low level for me.
- jok - does not support mobile and possibly has a little more than I needed.
In the end, I decided to go with sokol and sokol-zig .
While a little more lower level than raylib, it has:
- a modern clean api
- first class mobile support
- first class wasm support
UI
I’ve been working with dvui a lot recently. Unfortunately, it doesn’t support sokol. imgui is a better option.
There is even a template project that I could start from .
WASM first
To keep things straightforward, I decided to start with wasm. If I make the site mobile friendly, I could see how it goes and see if it needs a mobile version.
I will need some shared data storage and have been considering supabase , which has javascript libs. By using wasm , I can effectively shim in js functions to handle that instead of having to write bare rest calls from zig.
Structuring the project
Is this a zig project with a web component, vice versa or indeed two independent parts that work together.
I did a fair amount of web searching to see if there was some guidance I could I find for a good way to structure a relatively straightforward zig+js project.
I could not find one. In the end, I decided to keep it fairly straightforward.
- shine/
- src/ # zig code
- web/ # all the web stuff
Frontend
After a bit of research, and realising that I will probably need a little bit of supporting content around shine , I decided to go with lume
I used the simple-blog theme as a template to start from. I could have just pulled the template in but I wanted a custom homepage.
When I tried to add an index.md
, it complained about two files wanting to
write index.html
. From what I could find, the easiest way to override the
homepage was to just pick up the theme and edit it - which was easy enough.
WASM => frontend
I didn’t want to copy over the wasm and the js file every time, so I added a
couple of steps to build.zig
right after the link_step
(also included below)
|
|
These steps will copy across the wasm and the js file across to static/shine
.
I wanted to put the js in src/js
and the wasm in the static dir. However, the
js file expects the wasm in the same dir. I tried overriding locateFile
but it
didn’t work.
|
|
I was able to get lume to process the javascript file by add
ing it.
|
|
Conclusion
With all of these set up, I was able to run:
|
|
in one window. This command will rebuild wasm and provide it to lume whenever the zig code changes.
|
|
Running this in another window will mean that lume will rebuild on any changes, including a new wasm file and redeploy. The redeploy will trigger an auto-reload of the page as well if I have it in a browser.
I now effectively have automated reload with changes if I make changes in either zig or the frontend.
I don’t have hot reload - but this is pretty good for now.