Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

0002 Rust end to end

Status: accepted

Context

claudius has to do several different jobs well:

  • render a four-minute song of a dozen tracks, with convolution reverb and a mastering search, in seconds, many times over during evolution;
  • parse audio files, scripts and blueprints that come from other people and from assistants;
  • serve a studio natively and in a browser, an HTTP API and MCP, from one session;
  • listen: run CLAP and the AudioSet tagger, which earshot, the library that calibrates them, does in Python with PyTorch.

It also has to install as a program a musician downloads and runs, not as a development environment.

Decision

claudius is written in Rust throughout, as one Cargo workspace:

  • the engine (DSP, theory, rendering, the critic) uses rayon for parallel rendering and evolution;
  • the server uses tokio and axum, and the MCP tools rmcp;
  • the studio is egui, compiled natively and to WebAssembly (0008);
  • the scripting language is Rhai, which is itself written in Rust (0004);
  • audio decoding is symphonia, with ffmpeg only as an optional fallback;
  • earshot is ported to Rust (crates/earshot): its DSP reimplemented, the two models run as ONNX exports on ONNX Runtime through the ort crate, linked statically. Nothing needs Python at runtime.

Rejected: keeping earshot in Python and calling it as a subprocess, which would make every user install a Python environment with PyTorch, add seconds of startup to every verdict, and split the program in two. A C++ engine (a JUCE or similar stack) would be as fast but give up memory safety where claudius parses untrusted input, and make the build harder to keep portable. A JavaScript engine sharing code with Strudel would have made the web studio simpler and offline rendering of long, dense songs much slower.

Consequences

  • One language, one toolchain (rust-toolchain.toml), one dependency audit (cargo deny), and binaries that run without an interpreter. The claudius program carries the whole engine, the server and the studio.
  • The wire types (claudius-api) are shared by the server and the WebAssembly studio, so they cannot drift.
  • Parsing audio, scripts and JSON happens in memory-safe code; the remaining C is ONNX Runtime (running pinned, hash-checked models) and ffmpeg when it is installed.
  • The port of earshot is a maintenance cost: it has to match the Python original, which crates/earshot/tests/parity.rs checks against fixtures the Python version wrote. Regenerating those fixtures is the one task that still needs a Python environment, and only for developers.
  • ONNX Runtime arrives as a prebuilt static library downloaded at build time by ort. There is no build for Intel Macs, so that release target is marked experimental and fails for now.
  • Compile times are long (the dev profile optimises everything, because tests render audio), and contributors need to know Rust, which is a higher bar than Python for people who come from music.