Why maintain an engine fork? Swap your text shaper or layout solver with a single line in Cargo.toml, or wrap the frame pipeline to pace it and read every pass. Your existing div() views stay completely untouched.
5
Trait boundariesExposed at the facade
2
Ready to swapLive on crates.io
1
Ready to wrapbite-gp-pass 1.21.3
0
Engine forksMaintained across all
Two tiers
Replace it, or decorate it.
The distinction is not stylistic: it decides which seam a crate can plug
into and what publishing it commits the project to. Everything below is
one of the two.
Swap
Replace
Implements one of the seam traits and is installed at bootstrap in place of the default. One implementation per seam, chosen when the application is built.
replaces the algorithm
one per seam, never beside it
freezes the trait on publication
Wrap
Decorate
Implements FramePipeline and delegates: handed every pass of every frame it admits, it forwards the ones it does not change and wraps whatever pipeline is already installed.
decorates the frame pipeline
stacks in any order, any number
consumes a trait rather than freezing one
Swaps · The shelf
What you can swap out.
Every swappable boundary is defined in a standalone layer crate, backed
by a default implementation, and re-exported under
use gpui::*. Two have a published second
implementation; the other three do not, and this page says so rather
than implying one.
TextSystempublished
Text shaping, line layout, and glyph rasterization.
hook at the facadeApplication::with_text_system(Arc<dyn TextSystem>)
defined in
gpui_engine
default
DefaultTextSystem
over the host's own text backend
Pacing, presentation order, and render instrumentation.
hook at the facadeApplication::with_frame_pipeline(impl Fn(WindowId) -> Box<dyn FramePipeline>)
defined in
gpui_authoring
default
StandardImmediatePipeline
and its shipped decorators: .max_fps(n) and .instrumented(metrics)
second implementation
none published
The frame governor the one-pager shows is configuration of this default — ThrottledPipeline and InstrumentedPipeline, both in gpui_runtime — rather than a second implementation. Nothing out of tree publishes one. It is also the one seam a wrap can plug into.
Lowering the scene intermediate representation (IR) into GPU drawing commands.
hook at the facadenone — the trait is the boundary
defined in
gpui_engine
default
one per backend
MetalRenderer, DirectXRenderer, WgpuRenderer on Linux, and a headless one the test harness draws through
second implementation
none published
No Application setter installs one today: the trait is the boundary, and the platform picks the implementation. A second one needs a door before it can be a crate.
One wrap is published from its own repository; two ship inside the
facade as decorators you can stack without depending on anything. All
three implement the same trait, and all three forward the passes they do
not change.
bite-gp-pass
Published
Reads the frame's passes and the asks that did not draw: a policy-driven rate on one side, a ledger of what each pass cost on the other. A decorator you install without changing a view.
The facade's own rate cap: draw every Nth ask, decided from one number and the last frame.
caps a rate
whole intervals only
lib: gpui_runtime
InstrumentedPipeline
In the facade
The facade's own accounting: an Instant around each root pass, summed into running phase totals.
running totals
drawn frames only
lib: gpui_runtime
A wrap implements FramePipeline and delegates.
Every pass has a default that calls the Window
method behind it, so a decorator is only as transparent as the passes it
explicitly forwards — which is the whole of the contract.
Compose with any pipeline
A wrap goes where any pipeline goes — the factory you hand to
with_frame_pipeline — and stacks in any order
and any number. Nothing in the tree is forked, so there is no patch to
rebase when the engine moves. The published one is
bite-gp-pass, and
cargo add bite-gp-pass is the whole of its
install.
Installation
A swap is installed, not applied.
The two published swaps are ordinary crate dependencies. Nothing in the
tree is forked, so there is no patch to rebase when the engine moves —
and because each published package keeps its library target name,
use gpui_parley::… and
use gpui_morphorm::… are what your code
already says.
# both published swaps, one manifest
[dependencies]
bite-gpui = "1.21"
bite-gp-parley = "1.21"
bite-gp-morphorm = "1.21"
use gpui::*;
use gpui_morphorm::MorphormLayoutEngine;
use gpui_parley::ParleyTextSystem;
fnmain() {
application()
.with_text_system(ParleyTextSystem::new())
.with_layout_engine(|| Box::new(MorphormLayoutEngine::new()))
.run(|cx: &mutApp| { /* the same div() tree */ });
}
The trait stays where it is. It is declared in a
layer crate — gpui_engine for three of the
five — so implementing it is an impl in your
crate, not an edit to somebody else's.
The hook is one method, called before the first window.
A layout engine and a frame pipeline take factories because both are
per-window; a text system is one
Arc for the process.
The library target name is preserved. The package is
namespaced, the library is not, so an existing
use line keeps compiling and the manifest is
the only thing that moves.
Each swap lives in a repository of its own, with the
publisher that releases it, so it versions independently of the engine
it plugs into.
Open seams
What it takes to build a new backend.
We explicitly document the three unbuilt seams so external contributors
know exactly where the architectural boundaries lie:
What a second implementation would take
filed as usage projects, not as crates
seam
what it would take
filed as
FramePipeline
An out-of-tree pipeline. The shipped decorators are the pattern: a decorator forwards the passes it does not change and decides the ones it does, so a third-party one would wrap or replace StandardImmediatePipeline at the same hook.
pipeline-decorator
Platform
A platform that needs no display, so a CI job can render. The built-in route is the facade with its platform bundle dropped — default-features = false — plus the TestPlatform the test harness already runs on.
headless-platform
SceneRenderer
A renderer out of tree, which is what a raw render-pass blit would actually have to be — and a door at the facade first, because there is no setter to install one through.
scene-renderer
These are the categories the project files its own work under — a new
flavour of a swappable, a decorator, a new authoring surface — and
the demos page carries the whole taxonomy with what
each category is for.
The two that ship instead
The wgpu renderer and the frame governor are on the one-pager's shelf,
but neither is a swap: WgpuRenderer is the scene renderer
the Linux platform installs, and the governor is
StandardImmediatePipeline.max_fps(60) with
.instrumented(…) — shipped decorators, configured rather
than installed. The seam that replaces the renderer is
SceneRenderer, and it has no hook yet.
Limits
Two of five, not five of five.
The shelf is intentionally sparse: We only publish an
alternate crate when there is a distinct, measurable performance or
feature advantage. We don't build duplicate backends for the sake of
checking boxes.
Swaps are independent decisions:bite-gp-parley and
bite-gp-morphorm operate on entirely
different pipeline phases. You can use either one alone, combine both,
or keep the defaults. Neither implies or requires the other.
Every swap involves a trade-off: Parley adds BiDi
layout and font fallback at the cost of slightly higher per-glyph
instantiation overhead. Morphorm cuts layout frame time by up to 3.8×,
but omits complex CSS Grid track rules.
A wrap is the frame pipeline, and only the frame pipeline:
FramePipeline is the one seam that hands a
crate the frame's passes, so a decorator on
TextSystem or
LayoutEngine would have to be the
implementation — which is a swap.
Compose them on the one-pager
The Combo Studio is the interactive version
of this shelf: it stacks the add-ons and the platform backend, and shows
the
main.rs they produce. Two of its four add-ons are the
published crates above; the others are shipped configuration, as the
panel itself says.
Where they live
The published crates.
The three crates, and the repositories they are developed and released
from.