Skip to main content

Module design

Module design 

Source
Expand description

§Design

GPUI keeps application data in entities and element interaction state under stable ids. A view reads that state and describes the current frame. When an input handler changes an entity, notify schedules another render; painting then records shapes, text and images for the GPU.

The model grew out of work on the Zed editor. That history leaves three practical boundaries in application code: entity updates need a context, scrollable elements need stable ids, and custom controls must supply their own input and accessibility behavior. The sections below explain what GPUI provides at each boundary and what remains yours.

§GPU rendering

Layout runs on the CPU. Painting records primitives in a Scene: a div background becomes a rectangle, while text refers to rasterized glyphs in an atlas. Compatible primitives are batched for the renderer, and an existing glyph can be reused without rasterizing it again.

The GPU does not remove the CPU work of constructing or measuring elements. For 10,000 rows, a virtualized list limits construction to the viewport. GPU batching applies later, when the frame cycle paints those elements.

GPUI draws its own controls. Application code chooses their appearance; platform backends provide windows, input and operating-system services. Text input methods and accessibility still need explicit integration, so a custom control must implement the focus, input and accessibility behavior it needs. See text input and accessibility.

§Rebuilding views

A view’s Render::render method builds an element tree from current state. GPUI lays out and paints that tree; it does not reconcile a virtual DOM. The view can therefore describe its interface in one place instead of maintaining a separate update operation for each state transition.

Entities retain view state between frames. Elements can retain state too—scroll position and animation progress, for example—when they have stable ids. Recreating an element then does not reset its interaction state. Elements explains identity and the layout, prepaint and paint phases.

Rebuilding a complex view still costs CPU time, so GPUI keeps each view’s output and renders it again only when an entity or global it read is notified, the window is refreshed, or its bounds or text environment change. Performance covers when keeping views and list virtualization help.

§App-owned state

Several components often need to share mutable state. GPUI stores that state in the App and exposes typed Entity<T> handles. Reading or updating an entity requires a context. Handles can be cloned and moved into async work without keeping a borrow of the stored value alive.

The app coordinates entity lifetimes, observers and rendering dependencies. Updates are explicit: use Entity::update to mutate a value, then Context::notify to schedule dependent rendering or Context::emit to send a typed event. GPUI does not detect field mutations automatically. Ownership explains access and lifetimes; sharing state shows how separate views communicate.

§Explicit contexts

An App reference grants access to application services. Context<T> adds operations for the entity being updated, while Window provides layout, painting, focus and other window state. Passing these references to callbacks makes the required access visible in the signature and limits it to the call. Tests can provide the same access through a headless application.

Async work uses AsyncApp or AsyncWindowContext to regain access after an await. Those contexts are fallible because the app or window may have closed. Contexts explains how these types relate and which one to use.

§Style and layout

Elements carry styles set through Styled methods named after Tailwind CSS classes. Rust checks the method names and value types. Shared functions and components can reuse style builders, while theme state can live in a Global. Text properties inherit through the element tree; GPUI has no stylesheet selector cascade.

Layout uses Taffy for CSS flexbox and grid algorithms. Those algorithms resolve parent constraints together with child sizes. Layout and style connects the builder methods to those constraints and to custom element layout.

§Actions and key contexts

Keyboard commands have three parts: an Action names an operation, KeyBinding maps a keystroke to it, and KeyContext restricts where that binding applies. Focus determines the dispatch path. One action can serve a shortcut, menu item and application code without duplicating its handler.

This separation lets a user rebind a command and lets the same keystroke mean different things in an editor and a file list. Applications still define the commands and choose which controls can receive focus. Input dispatch explains matching and propagation; the keyboard guide shows how to connect them.

§Executors and tests

The foreground executor runs tasks on the UI thread through the platform event loop. A task may wait for I/O without blocking that thread, then update an entity through an async context. CPU-intensive work belongs on the background executor; in a single-threaded browser build it still shares the main thread, so split long work into smaller awaited steps.

Tests use a seeded scheduler and simulated time. They can reproduce task ordering, advance a timer without waiting in real time, and drive a window from input events. Executors explains polling and task lifetimes; the testing guide shows how to use those controls in a test.

§Scope and trade-offs

GPUI provides layout, styling, input dispatch, rendering and platform integration. The gpui_ce_elements crate adds editable text. Applications compose higher-level controls such as buttons, menus and dialogs from those pieces, and own their behavior and accessibility semantics.

Views and entities live on one UI thread. GPUI supports desktop platforms and browsers, with no mobile backend. It is pre-1.0, so API changes may require application updates. Platforms describes backend capabilities, comparison contrasts other toolkits’ approaches, and upstream explains the relationship to Zed’s GPUI.