#53

feat(dev): Blaze live reload for native GPUI apps (experimental)

Draft1byewants to merge intofrom

Adds experimental hot reload for native GPUI apps through Blaze. rake dev --live downloads a pinned, patched Blaze build, and the Rust supervisor drives the Blaze daemon. Rake applies patches from a 16 ms UI timer, and when a patch can't be applied it restarts the app without losing state. Apple Silicon macOS only. Plain rake dev is unchanged and still uses Cargo.

How it works

rake dev --live --bin rake-view
rake doctor --json
  • First run: downloads the archive pinned in crates/rake-cli/blaze-pin.toml from the 1bye/blaze v0.20261030.1-rake.1 release. It checks the SHA-256 and installs to ~/.rake/blaze/<version>/. Later runs check the saved archive again, and a wrong checksum is rejected.
  • Pinned compiler only: live mode never uses a blaze from PATH. RAKE_BLAZE=<path> overrides it explicitly. BLAZE_ARCHIVE=<file> supplies the archive bytes, which still have to match the checksum.
  • Configured automatically: the hybrid macro mode (BLAZE_PROC_MACRO_WASM=0, BLAZE_PROC_MACRO_SERVER=0), the bundled fixed macro server, a 64 MiB stack, and pathfinder_simd/pf-no-simd through the app's live feature. Apps must build a binary with --bin, not a cdylib.
  • rake doctor reports the platform, the pinned version, the checksum, and whether the macro server is present.

The Blaze fork

1bye/blaze, branch rake-patches, is upstream tag v0.20261030.1 (6560553) plus 17 commits:

  • 7 Rake fixes: WASI realpath, cross-file span_join, std symbol namespace, module_path! in symbol attributes, canonical CARGO, real rustc for build-script probes, AArch64 NEON intrinsics.
  • 8 earlier lab fixes: job limits, Wasm macro preparation, linking, ABI, x86 AES, and others.
  • Packaging: the matching fixed rust-analyzer-proc-macro-srv, and the Apple Silicon release recipe.

None of these fixes is upstream yet. See RAKE_FORK.md in the fork for how to upgrade it.

Measurements

Clean install from the GitHub release, app behind the editor, medians of six trials:

EditSave → applySave → redraw
view! text0.885 s1.063 s
Helper0.438 s0.675 s
  • State: all edits kept the PID and app state. A 64-edit run kept state through every edit, and the restart when the patch area filled worked.
  • Restarts: a struct field change restarts with state in about 4 s.
  • Cold build: about 3 minutes.
  • Idle CPU: 0.07% of one core.

App trial

All 13 examples, plus a scratch app using 13 common crates (image, tokio, reqwest, bundled rusqlite, sha2, regex and others), were run with the published bundle.

  • Coverage: 12 of 13 build and 11 start, with zero Blaze refusals and zero macro failures. The scratch app's outputs exactly match a Cargo build.
  • Text edits take 0.6–0.9 s in small apps and 2–3.6 s in larger ones (notes, preview, the scratch app). The time grows with how much cached code Blaze has to check again.
  • Helper edits take 0.3–0.9 s in every app.
  • Field changes: these restart by default. Checkpointed state is restored (notes, routing, desktop), and a notice in the CLI and in the app names whatever was reset. Restarts take 3.6–5.8 s. --require-state (or RAKE_REQUIRE_STATE=1) blocks the restart instead and keeps the old app running.
  • Excluded:
    • gpu-surface --features fast: Blaze links the window classes of both GPUI backends, which panics at startup.
    • inspector: its manifest is also broken under Cargo.
  • Live mode doesn't stage app bundle resources, so foundation reports its update status differently from Cargo.

Known issues

  • Most of a text edit's time is Blaze checking its cached code, so the sub-second target isn't met yet.
  • In an earlier run, the router remounted once at edit 30, which lost state. The cause is unknown and it hasn't happened again.
  • The first restart after a field change took 55 s.
  • External apps need a live = ["rake/live"] feature and the matching lockfile entry before --live works.
  • In strict mode, a blocked app gets Restart for every later edit, even after the field is reverted. Blaze keeps the type-change mark, so you have to restart the app yourself.
  • A restart restores only registered checkpoints. Fields outside a checkpoint (such as Kit's count) reset without warning.
  • Blaze-owned statics reset when their initializer is edited.
  • Linux, Windows and Intel Macs aren't supported.

Tests

940 workspace tests, 9 live-runtime, 14 supervisor and 4 installer tests passed. CI doesn't run real Blaze; the acceptance scripts are scripts/test-blaze-live.py and scripts/bench-blaze-live.py.

🤖 Generated with Claude Code