Zed’s GPUI is fast, but tightly coupled. bite-gpui breaks
the engine into five standalone crates. Tweak the frame pipeline, drop
in BiDi text layout, or run headless tests. Your div() code
stays 100% compatible.
Upstream GPUI gives you a fixed meal—take it or leave it.
bite-gpui lets you customize every layer. Pick your
add-on sides and sauces (Step 1), pair your platform drink (Step 2),
and ship. Zero engine forks, and your UI views never recompile.
Every bar below maps directly to an executable benchmark in the repository. Tested on real hardware — an Intel i7-8750H laptop running rustc 1.98.1 under normal background desktop load (no synthetic CPU pinning). Clone bite-gpui/gpui_parley , run the commands, and verify the timings yourself.
The problem: transforming font size dynamically on 30 lines per frame constantly thrashes standard glyph atlases.
The fix: rounding raster sizes to a deterministic lattice drops atlas cache misses from 154 a frame to zero, shrinking the atlas footprint from 32,508 entries down to 644.
Verify: $ cargo run --release --example raster_cost
The problem: upstream GPUI runs a face's bytecode hinting program per glyph instance (~31 µs each).
The fix: keying the cache directly to (face, size) builds just 30 instances per frame where an uncached hinting run would execute 3,480 times.
Verify: $ cargo run --release --example raster_cost
The problem: rasterizing dense text on every frame devours CPU cycles.
The fix: outlines are tessellated once (639 µs). Subsequent frames stream 218,322 pre-computed vertices straight to the GPU in 48 µs. You trade bus traffic for massive frame savings.
Verify: $ cargo run --release --example vector_cost
Start with the facade, then peel off layers as you need them.
# The whole stack, behind one facade
cargo add bite-gpui
# …or cherry-pick individual tiers
cargo add bite-gp-platform bite-gp-engine bite-gp-types
# …then swap a seam for a published alternative
cargo add bite-gp-parley
use gpui::*;
fn main() {
application().run(|cx: &mut App| {
cx.open_window(WindowOptions::default(), |_, cx| {
cx.new(|_| MyView)
}).unwrap();
});
}
use std::cell::RefCell;
use std::rc::Rc;
use gpui::*;
use gpui_parley::ParleyTextSystem;
fn main() {
let metrics = Rc::new(RefCell::new(PhaseMetrics::default()));
application()
.with_text_system(ParleyTextSystem::new())
.with_frame_pipeline({
let metrics = metrics.clone();
move |_window_id| {
Box::new(
StandardImmediatePipeline
.max_fps(60)
.instrumented(metrics.clone())
)
}
})
.run(|cx: &mut App| { /* … */ });
}
#[gpui::test]
fn renders_without_a_display(cx: &mut TestAppContext) {
let window = cx.update(|cx| {
cx.open_window(Default::default(), |_, cx| cx.new(|_| MyView))
.unwrap()
});
let mut cx = VisualTestContext::from_window(window.into(), cx);
// The window is drawn in-process: no display server, no GPU.
let bounds = cx.debug_bounds("submit").unwrap();
assert_eq!(bounds.size.height, px(32.));
}