New project
I’ve inherited a PWA app to fix up that is like a calculator for a tabletop game that looks pretty snazzy and works well. Installs on an iPad for offline use.
It’s about a 2mb bundle of html/css/js in one gigantic file of around 7000 lines of code. It’s mostly simple DOM with ui interactions and some dice rolling with a bunch of static lookup tables for result. No networking or REST involved (yet). There is nothing wrong with it, other than being a giant hairball of muck that is really hard to reason about, or make any more changes.
The original was vibe scaffolded out at great speed, then manually fixed up to clean up all the bugs. So taken that over now, with the goal to “please make it work properly” lol.
So I’m a couple of weeks in to rewriting the game logic into Zig and replacing the hairball with wasm + a small JS shim to bridge wasm to the DOM. Haven’t done anything at all with zig + wasm, so it’s all a learning experience for me here.
Observations - yeah doing anything useful in wasm requires this ridiculous shim layer in JS, which feels horrendous. But once the shim exists, it’s all reusable code, and doesn’t get any worse from there.
Pleasant surprises - porting the state representation to zig, and the game logic functions comes out nice and clean. Really not much code, and it’s very nicely organised now. Much less code that the original JS made it look like it might be.
Memory is easy - just alloc once up front, and use a fixed buffer allocator from there.
HTML templates all live inside the wasm now as static strings. Then use std print to an Io.Writer to render the templates. Can use Io.Writer’s automatic flush to effectively stream results to the JS shim, so no allocations needed there.
Long story short - 2mb original JS bundle now down to 200kb of wasm for the exact same templates and logic .. and the game logic is now locked up inside a far less hackable string of bytes. (** see comment below)
Not done yet, but just popped in here to say how pleasant it’s turning out so far, and no where near as daunting as it all sounds. I’m liking it.
Just write a state engine in zig, emit html fragments for the UI, and hook events through with data-on-click=zigFunction = pretty easy.
Doing the PWA manifest means it can install for offline use as an “app” that just works on iOS, Android, desktops, etc. No Apple Store BS to navigate. I like.