0008 egui for native and web
Status: accepted
Context
The studio is DAW-like: an arrangement of section blocks and track rows, a step sequencer, a mixer with faders and
meters, a waveform with a playhead, a script editor, a verdict panel. It has to run as a native window on the user’s
computer (claudius studio) and as a web page (claudius serve), including through a tunnel on a phone or a laptop
elsewhere. Almost all of it is custom drawing; few standard widgets fit.
The rest of claudius is Rust (0002), the team is small, and the server’s types should be the UI’s types.
Decision
The studio is written once with egui and eframe (crates/claudius-ui), compiled natively with the glow backend and
to wasm32-unknown-unknown with trunk. It depends only on claudius-api and talks to the engine only through the HTTP
API (0005), so the same code is a native window or a web page. Playback is rodio natively and an
HtmlAudioElement on the web. The widgets that matter (faders, knobs, meters, the arrangement grid) are drawn with
egui’s painter, and a built-in mock server lets the studio run, and be developed, without an engine.
Rejected: a web front end in a JavaScript framework with a native shell around it, which would mean two languages, the wire types written twice, and a build pipeline per language. A native toolkit per platform, which would triple the work and still leave the web. Rendering the UI on the server and streaming it, which does not work offline or through slow tunnels.
Consequences
- One studio for both targets, in one language, sharing types with the server; a change shows up in the window and the browser at once.
- egui redraws the whole UI each frame it paints, so the studio schedules repaints itself (while playing, while a job runs, while waiting on the network) to stay idle otherwise.
- Accessibility is weaker than native widgets or HTML give: screen-reader and keyboard support are limited to what egui provides. Text input and editing are egui’s too, which is enough for the script editor but not a code editor.
- The web build is a WebAssembly bundle of several megabytes that has to download before the studio appears.
- The two audio paths differ: natively the 24-bit WAV is decoded and played sample-accurately; on the web the browser plays the MP3, and a browser blocks sound until the user clicks.
- The native window cannot send a token, so it cannot open a token-protected claudius;
claudius studiosays so and points to the browser, which can. - Clippy has to run separately for the wasm target, because native builds never compile the
cfg(target_arch = "wasm32")code.