1---2name: gpui-kit3description: How to build desktop applications with GPUI Kit, the Rust framework published as the gpui-kit crate (GPUI plus gpui_kit::component, gpui_kit::base, gpui_kit::assets). Use when setting up a gpui-kit app, choosing or using a component (Button, Input, Select, Dialog, Sheet, Tabs, Sidebar, List, DataTable, Tree, Chart, etc.), handling component state, theming, or window overlays, and for GPUI mechanics: actions and keybindings, async tasks, contexts, custom elements, entities, events, focus, global state, layout and styling, ElementId, and tests. Holds the normative Coding Guides: read them before any architecture, state-ownership, public API, naming, or testing decision. Pairs with the gpui-kit-design-guides skill for the Design Guides.4---56# GPUI Kit78Applications depend on one crate, `gpui-kit`. GPUI is `use gpui_kit::*;`, and9each layer is reachable by name: `gpui_kit::component` (styled components),10`gpui_kit::base` (unstyled behavior), `gpui_kit::assets` (default icons),11`gpui_kit::platform`.1213## Read the Guides First1415Two guides hold the rules this skill assumes. They are requirements, not16inspiration. Read the guide file itself; do not answer from this page, from a17similar file in the codebase, or from training data.1819| Guide | Read before |20| ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- |21| Design Guides, skill `gpui-kit-design-guides` | Choosing components, layout, spacing, hierarchy, color, density, interaction states, overlays, motion, interface copy |22| [Coding Guides](references/coding-guides.md) | Crate layering, `RenderOnce` vs `Entity<T>`, state ownership, `ElementId`, events, focus, async, public API, naming, testing |2324Read the Design Guides first when the change has a visible surface: code25structure preserves product intent, it does not replace it. If the design26skill is not installed, fetch `https://gpui-kit.com/docs/design-guides.md`.27The coding guide is a verbatim copy of `https://gpui-kit.com/docs/coding-guides.md`,28so its links to `./design-guides.md` and `./getting-started.md` mean the design29skill and `https://gpui-kit.com/docs/getting-started.md`.3031### Coding Guides section map3233Read the whole guide for a new crate, module, or feature. For a narrow change,34read "Architecture at a glance" and "Rules for coding agents" first, then the35section for the change (`grep -n '^## ' references/coding-guides.md`).3637| Section | Read when |38| ------------------------------------ | ---------------------------------------------------------------------- |39| Architecture at a glance | Always; crate layering, ownership boundary |40| Bootstrap and root ownership | `main`, `init`, `Root`, window creation, app-level state |41| Understand GPUI's phases and contexts | Anything touching `App`, `Window`, `Context<T>`, render vs update |42| Choose the right unit | Deciding `RenderOnce` vs `Entity<T>` vs custom `Element` |43| State ownership | Where a piece of state lives, who mutates it, `Entity<State>` handles |44| Stable identity | `ElementId`, lists, repeated elements, keyed state |45| Rendering and composition | `render`, builder chains, `when`/`map`, child composition |46| Behavior and presentation boundary | `gpui-base` vs `gpui-component` vs application code |47| Theme and styling | `cx.theme()`, tokens, `Styled`, sizes, variants |48| Events, actions, and focus | `cx.emit`, `subscribe`, `actions!`, keybindings, `FocusHandle` |49| Async work and side effects | `cx.spawn`, `background_spawn`, `Task`, I/O, timers |50| Layout, measurement, and scrolling | Flex layout, sizing, `overflow`, scroll handles, measuring |51| Lists, tables, and large data | `VirtualList`, `List`, `DataTable`, delegates, large collections |52| Public API design | Anything `pub`: builders, private fields, setter and reader naming |53| Platform and capability boundaries | macOS/Windows/Linux/wasm differences, feature gates |54| File and naming conventions | New files, modules, type and method names, `Kind` suffix, `Context` |55| Testing strategy | What to test, `#[gpui_kit::test]`, `TestAppContext` |56| Performance rules | Render cost, allocation, re-render triggers |57| Common failure modes | Before finishing; invented APIs, state in render, index ids |58| Rules for coding agents | Always when an agent writes code |59| Implementation checklist | Before finishing; run every item against the work |6061### Non-negotiables6263A floor, not a substitute for the guides.6465- **Never invent an API.** Search the current source for the real signature.66 Do not translate a React, CSS, or older-GPUI example by analogy; a67 plausible-looking method that does not exist is the most common failure.68- **One dependency.** Applications depend on `gpui-kit` alone. GPUI is69 `use gpui_kit::*;`; the layers are `gpui_kit::component`, `gpui_kit::base`,70 `gpui_kit::assets`, `gpui_kit::platform`.71- **Framework owns behavior, application owns presentation.** Do not put72 colors, sizing, or layout in `gpui-base`; do not put interaction behavior in73 application styling code.74- **Stable identity.** Repeated elements need domain-derived `ElementId`s, not75 list indexes.76- **No `pub` fields across the seam.** Public data types use builders and77 reader methods.78- **Spell `Context` out.** `cx` is GPUI's; name anything else after what it79 holds.8081## Documentation8283- **Full reference**: fetch `https://gpui-kit.com/llms-full.txt`84- **Per-component API**: fetch `https://gpui-kit.com/docs/components/{name}.md`,85 e.g. `button.md`, `input.md`, `select.md`, `dialog.md`, `data-table.md`86- **Any site page** can be fetched as Markdown by appending `.md` to the URL8788## Quick Reference8990Setup and examples: [references/usage.md](references/usage.md).9192```rust93use gpui_kit::*;94use gpui_kit::component::Root;9596gpui_kit::application()97 .with_assets(gpui_kit::assets::Assets)98 .run(|cx| {99 gpui_kit::init(cx); // first, before anything else100 // ... open_window(..., |window, cx| cx.new(|cx| Root::new(view, window, cx)))101 });102```103104- **Stateless** (`RenderOnce`): build in `render`:105 `Button::new("save").primary().label("Save").on_click(|_, _, _| {})`106- **Stateful**: hold `Entity<State>` in the view, pass a reference in `render`:107 `let input = cx.new(|cx| InputState::new(window, cx));` then `Input::new(&self.input)`108- **Sizes**: `.xsmall()` `.small()` `.medium()` (default) `.large()`109- **Theme**: `cx.theme().primary` · `.background` · `.foreground` · `.border` · `.muted`110- **Overlays**: `window.open_dialog(...)`, `open_sheet(...)`, `push_notification(...)`111 via `gpui_kit::component::WindowExt`112113## Component Catalog114115Import paths are relative to `gpui_kit::component::`, so `input::{Input, InputState}`116means `use gpui_kit::component::input::{Input, InputState};`. For the full API117fetch the component's `.md` doc.118119### Input & Form120121| Component | Import | Notes |122| ------------- | ----------------------------------------------- | -------------------------------------------- |123| `Input` | `input::{Input, InputState}` | Stateful. Text, password, mask, validation |124| `Textarea` | `input::{Textarea, TextareaState}` | Stateful. Multi-line text |125| `Editor` | `input::{Editor, EditorState}` | Stateful. Code editor, `tree-sitter` feature |126| `NumberInput` | `input::{NumberInput, NumberInputEvent}` | Stateful. Numeric with step |127| `OtpInput` | `input::OtpInput` | Stateful. One-time password |128| `Select` | `select::{Select, SelectState}` | Stateful. Dropdown picker |129| `Combobox` | `combobox::{Combobox, ComboboxState}` | Stateful. Searchable select |130| `Checkbox` | `checkbox::Checkbox` | Stateless. `on_click` receives `&bool` |131| `Switch` | `switch::Switch` | Stateless. Toggle |132| `Radio` | `radio::{Radio, RadioGroup}` | Stateless. |133| `Slider` | `slider::{Slider, SliderState}` | Stateful. |134| `Toggle` | `button::Toggle` | Stateless. |135| `Rating` | `rating::Rating` | Stateless. |136| `Stepper` | `stepper::Stepper` | Stateless. Multi-step progress |137| `ColorPicker` | `color_picker::{ColorPicker, ColorPickerState}` | Stateful. |138| `DatePicker` | `date_picker::{DatePicker, DatePickerState}` | Stateful. |139| `Calendar` | `calendar::{Calendar, CalendarState}` | Stateful. Inline month view |140| `Form` | `form::{v_form, h_form, field}` | Layout container for form fields |141142### Display & Feedback143144| Component | Import | Notes |145| ----------- | ----------------------------------------- | ------------------------------------- |146| `Button` | `button::{Button, ButtonGroup}` | Stateless. Primary UI action |147| `Icon` | `{Icon, IconName}` | Stateless. Lucide icons |148| `Badge` | `badge::Badge` | Stateless. |149| `Tag` | `tag::Tag` | Stateless. Closable tags |150| `Avatar` | `avatar::Avatar` | Stateless. |151| `Label` | `label::Label` | Stateless. Form label |152| `Kbd` | `kbd::Kbd` | Stateless. Keyboard key display |153| `Alert` | `alert::Alert` | Stateless. Info/success/warning/error |154| `Spinner` | `spinner::Spinner` | Stateless. Loading indicator |155| `Skeleton` | `skeleton::Skeleton` | Stateless. Loading placeholder |156| `Shimmer` | `shimmer::{ShimmerText, ShimmerStyle}` | Stateless. Streaming-text shimmer |157| `Marker` | `marker::{Marker, MarkerVariant}` | Stateless. Inline status marker |158| `Progress` | `progress::{Progress, ProgressCircle}` | Stateless. |159| `Tooltip` | `tooltip::Tooltip` | Via `.tooltip()` on elements |160| `HoverCard` | `hover_card::{HoverCard, HoverCardState}` | Stateful. |161| `Clipboard` | `clipboard::Clipboard` | Stateless. Copy button |162| `TextView` | `text::TextView` | `TextView::markdown(id, text)`, HTML too |163| Image | `gpui_kit::{img, ImageSource, ObjectFit}` | GPUI's `img()` element |164165### Overlay & Popups166167| Component | Import | Notes |168| ---------------- | ------------------------------------------------- | ---------------------------------------- |169| `Dialog` | `dialog::Dialog` + `WindowExt` | Via `window.open_dialog(...)` |170| `AlertDialog` | `WindowExt` | Via `window.open_alert_dialog(...)` |171| `Sheet` | `sheet::Sheet` + `WindowExt` | Side panel, via `window.open_sheet(...)` |172| `Notification` | `notification::Notification` + `WindowExt` | Via `window.push_notification(...)` |173| `Popover` | `popover::Popover` | Floating overlay |174| `Menu` | `menu::{PopupMenu, DropdownMenu}` | Context menus |175| `DropdownButton` | `button::DropdownButton` | Button with dropdown menu |176| `Command` | `command::{Command, CommandState, CommandGroup}` | Stateful. Command palette |177| Focus trap | `FocusTrapElement` | `.focus_trap(id, &handle)` on a container; `Dialog` and `Sheet` have it built in |178179### Navigation & Layout180181| Component | Import | Notes |182| ----------------- | ------------------------------------------------------------------------ | ------------------------- |183| `Tabs` / `TabBar` | `tab::{Tab, TabBar}` | Tabbed interface |184| `Sidebar` | `sidebar::{Sidebar, SidebarMenu, ...}` | App navigation panel |185| `TitleBar` | `TitleBar` | Window title bar |186| `StatusBar` | `status_bar::StatusBar` | Window status bar |187| `Breadcrumb` | `breadcrumb::Breadcrumb` | Navigation breadcrumb |188| `Pagination` | `pagination::Pagination` | Page navigation |189| `Accordion` | `accordion::Accordion` | Collapsible sections |190| `Collapsible` | `collapsible::Collapsible` | Single collapsible |191| `GroupBox` | `group_box::GroupBox` | Labeled container |192| `Resizable` | `resizable::{h_resizable, v_resizable, resizable_panel, ResizableState}` | Draggable split panes |193| `Scrollbar` | `scroll::Scrollbar` | Custom scrollbar |194195### Data Display196197| Component | Import | Notes |198| ----------------- | ----------------------------------------------- | ----------------------------- |199| `DataTable` | `table::{DataTable, TableState, TableDelegate}` | Stateful. Full-featured table |200| `Table` | `table::{Table, ...}` | Simpler table |201| `VirtualList` | `{v_virtual_list, h_virtual_list}` | High-perf large lists |202| `List` | `list::{List, ListState, ListDelegate}` | Stateful. Searchable list |203| `Tree` | `tree::{Tree, TreeState, TreeItem, TreeEntry}` | Stateful. Hierarchy |204| `DescriptionList` | `description_list::DescriptionList` | Key-value pairs |205| `Settings` | `setting::Settings` | Settings panel |206207### Chat & Messaging208209| Component | Import | Notes |210| ----------------- | -------------------------------------------------------- | ------------------------------------- |211| `Message` | `message::{Message, MessageContent, MessageAlignment}` | Stateless. Chat message row |212| `Bubble` | `bubble::{Bubble, BubbleContent, BubbleVariant}` | Stateless. Message bubble |213| `Attachment` | `attachment::{Attachment, AttachmentContent, ...}` | Stateless. File/media attachment card |214| `MessageScroller` | `message_scroller::{MessageScroller, MessageScrollerState}` | Stateful. Auto-scrolling message list |215216### Charts217218| Component | Import | Notes |219| --------- | --------------------------------------------------------------- | ------------------------------ |220| `Chart` | `chart::{AreaChart, BarChart, LineChart, PieChart, RadarChart}` | Bar, line, area, pie charts |221| `Plot` | `plot::Plot` | `#[derive(IntoPlot)]` for data |222223## GPUI References224225Load the file for the mechanism the task touches. Each file starts with a226contents line.227228| Topic | File | Load when |229| --------------------------- | ------------------------------------------------------ | --------------------------------------------------------------- |230| Actions & keybindings | [action.md](references/gpui/action.md) | `actions!`, `bind_keys`, `on_action`, `key_context` |231| Async & background tasks | [async.md](references/gpui/async.md) | `cx.spawn`, `background_spawn`, `Task`, async I/O |232| Context management | [context.md](references/gpui/context.md) | `App`, `Window`, `Context<T>`, `AsyncApp` |233| Custom elements (low-level) | [element.md](references/gpui/element.md) | `Element` trait, `request_layout`, `prepaint`, `paint` |234| Entity state | [entity.md](references/gpui/entity.md) | `Entity<T>`, `WeakEntity`, state management |235| Events & subscriptions | [event.md](references/gpui/event.md) | `cx.emit`, `cx.subscribe`, `cx.observe` |236| Focus & keyboard nav | [focus-handle.md](references/gpui/focus-handle.md) | `FocusHandle`, `track_focus`, Tab navigation |237| Global state | [global.md](references/gpui/global.md) | `Global` trait, `cx.set_global`, app-wide config |238| Layout & styling | [layout-style.md](references/gpui/layout-style.md) | `div()`, `h_flex()`, `v_flex()`, flexbox, overflow, positioning |239| ElementId | [element-id.md](references/gpui/element-id.md) | `ElementId`, `.id()`, uniqueness rules, stateful elements |240| Testing | [test.md](references/gpui/test.md) | `#[gpui_kit::test]`, `TestAppContext`, `VisualTestContext` |241242Deep dives, for when the topic file is not enough:243244- **Element trait**: [element-api.md](references/gpui/element-api.md) (complete API, hitbox, events) ·245 [element-patterns.md](references/gpui/element-patterns.md) (text, interactive, container, composite) ·246 [element-examples.md](references/gpui/element-examples.md) (full examples) ·247 [element-best-practices.md](references/gpui/element-best-practices.md) (performance, state, pitfalls) ·248 [element-advanced.md](references/gpui/element-advanced.md) (custom layouts, async updates, virtual lists)249- **Entities**: [entity-api.md](references/gpui/entity-api.md) (complete API, lifecycle) ·250 [entity-patterns.md](references/gpui/entity-patterns.md) (model-view, cross-entity, observer) ·251 [entity-best-practices.md](references/gpui/entity-best-practices.md) (memory, performance) ·252 [entity-advanced.md](references/gpui/entity-advanced.md) (collections, registry, debounce, state machines)253- **Testing**: [test-examples.md](references/gpui/test-examples.md) (organization, setup, assertions, running tests) ·254 [test-reference.md](references/gpui/test-reference.md) (re-entrancy, property tests, mocking)