← Overview GPUI / Framework
Foundation Layer

GPUI — The UI Framework

GPUI is Zed's custom reactive UI framework. It provides the entity system, event/action dispatch, concurrency primitives, and the rendering loop that everything else is built on top of.

Application Initialization

The entry point (main.rs:193) creates an Application, registers global services, then calls app.run() which starts the platform event loop and hands control to GPUI.

main() — sets up DB, session, HTTP client, language registry
Application::new(platform) — wraps platform in Rc<AppCell>
app.run(|cx| { ... }) — enters the OS event loop; closure opens the first workspace
Platform event loop — continuously dispatches events until quit
Application / App app.rs:140 / :596
// Root handle — cheaply cloneable Rc wrapper pub struct Application(Rc<AppCell>); // The actual state, accessed via &App / &mut App pub struct App { platform: Rc<dyn Platform>, // macOS/Linux/Windows impl text_system: Arc<TextSystem>, windows: HashMap<WindowId, Window>, entities: EntityMap, // all live Entity<T> values globals: HashMap<TypeId, AnyBox>, pending_effects: VecDeque<Effect>, // queued notify/emit effects }
Entity System

All mutable application state lives in entities. An Entity<T> is a reference-counted handle to a value of type T stored inside GPUI's entity map. GPUI routes notifications and events through this system, ensuring the single-threaded UI loop has consistent state.

Key rule: Never hold a borrow across an .update() call — GPUI will panic if two mutable borrows overlap. Use the inner cx provided by the closure, not the outer one.
Entity<T> API app.rs
// Reading state entity.read(cx) // → &T entity.read_with(cx, |t, cx| ...) // → R // Mutating state entity.update(cx, |t: &mut T, cx: &mut Context<T>| ...) entity.update_in(cx, |t, window, cx| ...) // also takes Window // Weak references (avoid memory leaks in cyclic structures) entity.downgrade() // → WeakEntity<T> weak.upgrade(cx) // → Option<Entity<T>>

When state changes, call cx.notify() inside an .update() closure. GPUI queues a redraw for views that subscribe to this entity, and calls cx.observe callbacks.

Input & Action Dispatch

This is the path a keystroke takes before reaching any editor code:

1
Platform receives OS event
macOS NSApplication / Linux XCB / Windows message loop delivers a key-down event to GPUI's platform shim.
2
Keystroke → Action via Keymap
keymap.rs matches the keystroke (and any pending chord state) against the active bindings. If matched, it produces a boxed dyn Action value.
3
App::dispatch_action()
app.rs:2207 routes the action to the focused window. The dispatch travels through the element tree in capture phase (root → leaf) then bubble phase (leaf → root), calling .on_action() handlers registered on each element.
4
Action handler executes
The focused view's handler (e.g. Editor::move_left) is called. It mutates entity state and calls cx.notify() to schedule a re-render.
Concurrency Primitives

GPUI's rule: all entity access happens on one foreground thread. Background work runs on a separate thread pool and communicates results back via foreground tasks.

spawn / background_spawn app.rs
// Foreground task — has access to App / entities let task = cx.spawn(async move |mut cx| { entity.update(&mut cx, |t, cx| { ... })?; }); // Background task — no entity access; returns a value let result = cx.background_spawn(async move { expensive_computation() // runs on thread pool }).await; // Dropping a Task cancels it; detach to let it run forever task.detach_and_log_err(cx);
Pattern: syntax re-parsing runs in background_spawn. The result is sent back to a foreground spawn task that updates the Buffer entity and calls cx.notify().
Rendering Loop

After cx.notify() is called, GPUI schedules a frame. On the next frame tick:

1
Render trait called
For each dirty view, GPUI calls T::render(&mut self, window, cx) which returns an element tree.
2
Layout phase
GPUI performs a flexbox layout pass over the element tree, computing pixel bounds for each element.
3
Paint phase
Each element's paint(bounds, scene, cx) is called. Elements emit quads, glyphs, underlines, paths, and sprites into the Scene.
4
WGPU submission
The Scene is handed to gpui_wgpu, which builds GPU draw calls and presents the framebuffer. See Rendering Pipeline.
Code References