← Design · c130

research/gpui.md

GPUI: Zed's framework

Use this file to understand the engine under GPUI Kit before you read the kit's docs: how state, views and elements fit together, what the GPU renderer does and does not do, what each OS gives the app, and what "native" means for the screens we will draw (D2). A builder reads the programming model and the platform layer; a designer reads the renderer, text and "native" sections. Companion: gpui-kit.md. Every source below was read on 2026-11-09.

What GPUI is

The programming model

Three "registers", in the README's words. — https://raw.githubusercontent.com/zed-industries/zed/main/crates/gpui/README.md

RegisterWhat it isWhat a builder does
State: entitiesEvery model and view is owned by one top-level App; cx.new(...) returns an Entity<T>, "an inert identifier plus a compile-time type tag". Context<T> is the App seen from one entity.Keep state in entities; update / read; cx.notify() tells observers; emit / subscribe for events. Effects flush at the end of each update, so there is no re-entrancy. — https://zed.dev/blog/gpui-ownership
Declarative UI: views"A view is simply an Entity that can be rendered, by implementing the Render trait." render(&mut self, window, cx) -> impl IntoElement builds a fresh element tree each pass.Compose div() trees with the Tailwind-named Styled methods: flex(), flex_col(), gap_2(), p_4(), w_64(), bg(...), text_color(...), border_1(), rounded(...), text_sm(), .when(cond, ...), hover(...). Sizes are rem-based. — https://gpui-kit.com/docs/style
Imperative UI: elementsAn Element is one node in the tree GPUI builds for a frame, with three phases: request_layout → prepaint → paint. Taffy (flexbox and grid) resolves bounds between the first two.Write a custom element only when nothing composes; canvas(prepaint, paint) for short-lived drawing. — https://gpui-kit.com/docs/element
  • Hybrid, in practice. "Retained" describes the entity state and the caches; "immediate-style" describes how render rebuilds the description each time it is needed. RenderOnce "does not mean once per display frame." — https://gpui-kit.com/docs/fps
  • Redraw on demand. "An Entity mutation followed by cx.notify() marks that Entity for rendering… A frame tick alone does not redraw an unchanged window." An unconditional notify() or request_animation_frame() inside render "creates continuous work even when the UI is idle." This is the rule that keeps an idle app at zero CPU. — https://gpui-kit.com/docs/window, https://gpui-kit.com/docs/fps
  • Actions and keys. actions!(ns, [Name]) defines unit actions; KeyBinding::new("cmd-s", Save, Some("Editor")) binds them (static strings since gpui-pre 0.3.10); dispatch follows the focus path; the same action drives a button, a palette entry and a native menu item. — https://gpui-kit.com/docs/action, https://gpui-kit.com/docs/keybinding
  • Testing built in. #[gpui::test], TestAppContext (add_window, dispatch_action, simulate_keystrokes, run_until_parked) and VisualTestContext (simulate_click, draw). The kit wraps these as headless UI tests. — https://raw.githubusercontent.com/zed-industries/zed/main/crates/gpui/src/app/test_context.rs

The renderer

The platform layer

One crate per OS; gpui_platform::application() "picks the windowing and text backends for the host OS". — https://raw.githubusercontent.com/zed-industries/zed/main/crates/gpui_platform/src/gpui_platform.rs

The OS givesThroughNotes
The windowWindowOptions: bounds, titlebar (hidden for a custom-drawn one on macOS and Windows), kind (Normal, PopUp, Floating, Dialog, LayerShell), window_background (Opaque, Transparent, Blurred, Mica), window_decorations (Server or Client on Linux), app_id, min sizeMethods: set_window_title, zoom_window, minimize_window, toggle_fullscreen, set_window_edited, appearance(), observe_window_appearance, set_rem_size. — https://raw.githubusercontent.com/zed-industries/zed/main/crates/gpui/src/platform.rs
MenusApp::set_menus, set_dock_menu, add_recent_document, update_jump_list (Windows); Menu, MenuItem::{Separator, Submenu, SystemMenu, Action}, OsAction::{Cut, Copy, Paste, SelectAll, Undo, Redo}The macOS menu bar is native. Windows and Linux have no global menu bar; the kit draws one. — https://raw.githubusercontent.com/zed-industries/zed/main/crates/gpui/src/platform/app_menu.rs
Dialogsprompt_for_paths, prompt_for_new_path; native alerts via Window::prompt(PromptLevel, …); set_prompt_builder to replace them— https://raw.githubusercontent.com/zed-industries/zed/main/crates/gpui/src/app.rs
Clipboardread_from_clipboard, write_to_clipboard
URLsApplication::on_open_urls, App::open_url, App::register_url_scheme(scheme)The hooks for a deep link in the Connect flow (platform.md).
Notificationsshow_system_notification(SystemNotification { tag, title, body, actions }); gpui_macos links objc2-user-notifications, gpui_linux uses notify-rustmacOS requires a real signed .app bundle; Linux needs a session D-Bus and a notification daemon. — https://gpui-kit.com/docs/system-notification
Credentialswrite_credentials / read_credentials / delete_credentials, keychain-backedA home for the plane's connect token.
Otherreveal_path, open_with_system, on_quit, on_reopen, activate, hide, displays, keyboard layout, screen capture (feature)
Not a trayNo tray or status-item API exists in GPUI. A 2024 PR to add Linux tray icons was closed unmerged. A third-party crate gpui-tray 0.3.0 exists (5 stars).The spike's first platform question. — https://github.com/zed-industries/zed/pull/13098, https://crates.io/api/v1/crates/gpui-tray

Windows has been a supported Zed platform since 2025-10-15 ("Windows is now a fully supported platform for Zed"); Linux since 2024-07-10. — https://zed.dev/blog/zed-for-windows-is-here, https://zed.dev/blog/zed-on-linux

Text rendering

What "native" means here (D2)

GPUI draws every control itself, on the GPU, the way Flutter does. There is no NSButton, no Win32 edit control, no GTK widget behind a kit button. The operating system provides the window and its chrome, the menu bar (macOS), dialogs, the clipboard, notifications, the keychain and URL handling; the app provides the pixels inside the window.

What follows for us:

  1. Stakeholders should expect a native binary and a native window, not OS-drawn buttons. Say so in the pitch. The upside is that the same screen looks the same on three OSes and every pixel can carry the brand (D5 keeps that subtle).
  2. Accessibility is published, not inherited. A custom-drawn control has no semantics unless the app reports them. GPUI publishes an AccessKit tree since 2026-05-27; a node is reported only when it has an ElementId and a role. Zed keeps it off by default and "doesn't support screen readers" today by a maintainer's own words. The kit reports roles on its components and tests them headlessly, but no screen-reader run is reported by anyone. Treat screen-reader usability as unproven and check it on each OS in c131 (D10 there). — https://github.com/zed-industries/zed/pull/56065, https://github.com/zed-industries/zed/issues/41138, https://gpui-kit.com/docs/accessibility
  3. Platform conventions still matter. Command vs Control, the menu bar on macOS, window controls on Linux, system light/dark: the kit's design guide lists these as the places where "native" is earned.

Where to learn GPUI

  • The README ("Intro to GPUI"), docs/contexts.md, docs/key_dispatch.md, the module docs on ownership and on accessibility, and 46 examples (hello_world, data_table, uniform_list, set_menus, system_notifications, a11y, testing, drag_drop, window_positioning). — https://www.gpui.rs/, https://api.github.com/repos/zed-industries/zed/contents/crates/gpui/examples
  • Zed's posts, in reading order: "Leveraging Rust and the GPU to render user interfaces at 120 FPS" (2023-03-07), "Ownership and data flow in GPUI" (2024-01-25, updated 2025-12-12), "Optimizing the Metal pipeline to maintain 120 FPS" (2024-02-07). — https://zed.dev/blog
  • The README's own advice: "the best way to learn about these APIs is to read the Zed source code or drop a question in the Zed Discord".
  • The most complete GPUI manual today is GPUI Kit's docs, written against the snapshot the kit pins: Entity, Context, Render, Element, Window, Style, Action, KeyBinding, Focus, Task, Fonts, Animation, Accessibility, Testing, WebAssembly, FPS. — https://gpui-kit.com/docs, https://gpui-kit.com/llms-full.txt
  • Community books exist (an "Unofficial GPUI Cheat Book", two gpui-books); their currency is unverified.

Open questions

  1. Will Zed publish gpui to crates.io again, or is Longbridge's weekly gpui-pre the distribution for everyone else? Nothing from Zed says.
  2. Is any GPUI app usable with VoiceOver, NVDA or Orca today?
  3. RTL: no timeline.
  4. Hinting and subpixel policy per OS, and how the same text differs across them.

Sources

https://www.gpui.rs/ · https://raw.githubusercontent.com/zed-industries/zed/main/crates/gpui/README.md · https://zed.dev/blog/gpui-ownership · https://zed.dev/blog/videogame · https://zed.dev/blog/120fps · https://zed.dev/blog/zed-1-0 · https://zed.dev/blog/zed-for-windows-is-here · https://zed.dev/blog/zed-on-linux · https://zed.dev/blog/community-champion-jason-lee · https://zed.dev/faq · https://zed.dev/releases/stable · https://crates.io/api/v1/crates/gpui · https://crates.io/api/v1/crates/gpui-pre · https://crates.io/api/v1/crates/gpui-tray · https://github.com/zed-industries/zed/pull/13098 · https://github.com/zed-industries/zed/pull/46758 · https://github.com/zed-industries/zed/pull/49277 · https://github.com/zed-industries/zed/pull/56065 · https://github.com/zed-industries/zed/issues/41138 · https://github.com/zed-industries/zed/issues/31102 · the gpui crate sources under https://github.com/zed-industries/zed/tree/main/crates (gpui/src/platform.rs, app.rs, window.rs, scene.rs, text_system.rs, _accessibility.rs, _ownership_and_data_flow.rs, app/test_context.rs, platform/app_menu.rs; gpui_platform, gpui_wgpu, gpui_windows, gpui_macos, gpui_linux Cargo.toml) · https://gpui-kit.com/docs (element, window, fps, style, action, keybinding, fonts, text-system, accessibility, system-notification, native-extension, design-guides, installation) · https://raw.githubusercontent.com/longbridge/gpui-fast/main/README.md

Qpoint Brand Style Guide