This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Before changing UI, interaction, interface language, layout, styling, components, or application architecture, read and follow the repository's canonical guides:
These guides are requirements, not optional inspiration. Do not copy generic web conventions, infer a design system from one existing screen, or add a control merely because the underlying feature exists. Preserve the documented task hierarchy, interaction promise, desktop conventions, spacing, alignment, theme tokens, component boundaries, naming, and crate architecture. Review the finished work against both guides before considering it complete.
For Chinese documentation and UI, apply the terminology rules in Design Guides. Keep established framework, component, and API names in their canonical English form when translation would reduce precision; write the surrounding Chinese as natural Chinese rather than word-for-word translation.
GPUI Kit is a Rust desktop application framework built on GPUI, published at https://gpui-kit.com. It ships as three crates: gpui-base (unstyled behavior and infrastructure), gpui-shell (JavaScript extensions for a Rust host), and gpui-component (GPUI Component, the styled component library with 60+ cross-platform desktop UI components, inspired by macOS/Windows controls and combined with shadcn/ui design). Applications depend on the umbrella crate gpui-kit (crates/kit), which pins the matching gpui-pre-* snapshot of GPUI and puts GPUI at its root (use gpui_kit::*;) with gpui_kit::platform, gpui_kit::base, gpui_kit::component and gpui_kit::assets reachable by name, so they never list GPUI itself. gpui-shell is not part of gpui-kit and is not published yet (its llrt_* dependencies are git-only); use it as a git dependency.
This is a Rust workspace project with the following main crates:
crates/kit- Umbrella crate applications depend on (published asgpui-kit)crates/component- Core UI component library (published asgpui-component)crates/story- Gallery application for showcasing and testing componentscrates/story-web- Web version of the story gallery (using WebAssembly)crates/component-macros- Procedural macros (IntoPlotderive)crates/assets- Static assetscrates/webview- WebView component supportexamples/- Various example applications
# Run Story Gallery (component showcase application)
cargo run
# Run individual examples
cargo run --example hello_world
cargo run --example table
# Build the project
cargo build
# Lint check
cargo clippy -- --deny warnings
# Format check
cargo fmt --check
# Spell check
typos
# Check for unused dependencies
cargo macheteNote: Per user configuration, tests do not need to be run.
For pure UI visual or sizing adjustments, do not add automated tests solely to assert presentation dimensions. Add tests when the change affects behavior, interaction, data flow, or prevents a meaningful regression.
# Run all tests
cargo test --all
# Run tests for a specific crate
cargo test -p gpui-component
# Run doc tests
cargo test -p gpui-component --doc# View FPS on macOS (using Metal HUD)
MTL_HUD_ENABLED=1 cargo run
# Profile performance using samply
samply record cargo runThe implemented foundation architecture is documented in
docs/ARCHITECTURE.md, with styling and motion rules in
docs/STYLING-AND-MOTION.md. Preserve these constraints when designing or
implementing this architecture:
-
Do not modify
gpui-baseunless the user explicitly requests a Base-layer change. By default, implement component behavior and visual styling incrates/componentor the application layer. -
Keep GPUI Kit as the ecosystem and product brand;
gpui-componentis its styled component layer, alongsidegpui-baseandgpui-shell. -
Name the foundation crate
gpui-base. -
Follow the ownership boundary: the framework owns behavior and infrastructure; the application owns component source and visual style.
-
Keep the base layer visually unopinionated. It may provide interaction behavior, accessibility, focus, overlay and popup infrastructure, positioning, animation, virtual lists, dock infrastructure, and semantic design tokens.
-
Theme APIs must expose semantic tokens (colors, spacing, radius, typography, and shadows), not an ever-growing set of component-specific styling fields.
-
Keep source distribution or registry tooling above the
gpui-baseseam; no registry or CLI crate is currently part of the workspace. -
Preserve 100% backward compatibility for existing consumers, including current imports such as
use gpui_kit::component::button::Button;.
Critical requirement: You must call gpui_component::init(cx) at your application's entry point before using any GPUI Component features.
fn main() {
let app = Application::new();
app.run(move |cx| {
// This must be called first
gpui_component::init(cx);
cx.spawn(async move |cx| {
cx.open_window(WindowOptions::default(), |window, cx| {
let view = cx.new(|_| MyView);
// The first level view in a window must be a Root
cx.new(|cx| Root::new(view, window, cx))
})
.expect("Failed to open window");
}).detach();
});
}Root is the top-level view for a window and manages:
- Sheet (side panels)
- Dialog (dialogs)
- Notification (notifications)
- Keyboard navigation (Tab/Shift-Tab)
The first view of every window must be a Root.
- Uses
Themeglobal singleton for theme configuration - Supports light/dark mode switching
- Access theme via
ActiveThemetrait:cx.theme() - Theme configuration includes:
- Colors (
ThemeColor) - Syntax highlighting theme (
HighlightTheme) - Font configuration (system font and monospace font)
- UI parameters like border radius, shadows
- Scrollbar display mode
- Colors (
Layout behavior lives in crates/base/src/dock; crates/component/src/dock is a
presentation skin (DockSkin) over it. See docs/ARCHITECTURE.md.
LayoutTree: Pure-data layout tree, the single source of truth.NodeKind::Split/Tabs/Tiles: containers, addressed byNodeId- Panels are addressed by
PanelId; the tree holds no entity handles
DockArea: Owns the center and dock trees, reconciles them into a cache of container entities keyed byNodeIdTabGroup/TilesState: TheTabs/Tilescontainer entitiesPanel: Split at the seam —gpui_base::dock::Panelfor behavior,gpui_component::dock::Panelfor presentation; a panel implements bothPanelRegistry: Resolves a persistedpanel_nameback to a panel type
The Dock system supports:
- Panel drag-and-drop reordering
- Panel zoom
- Layout locking
- Layout serialization/restoration
Text input system based on Rope data structure:
- InputState: Input state management
- Rope: Efficient text storage (from ropey crate)
- LSP integration support (diagnostics, completion, hover)
- Syntax highlighting support (Tree-sitter)
- Multiple input modes:
- Regular input (
Input) - Number input (
NumberInput) - OTP input (
OtpInput)
- Regular input (
- Stateless design: Use
RenderOncetrait, components should be stateless when possible - Size system: Supports
xs,sm,md(default),lgsizes viaSizabletrait. - Mouse cursor: Buttons use
defaultcursor notpointer(desktop app convention), unless it's a link button - Style system: Provides CSS-like styling API via
Styledtrait andElementExtextensions - Base controls are no-style: Base controls and parts do not install layout,
positioning, colors, sizing, gaps, radius, borders, shadows, variants, or animation.
Complete presentation belongs to
crates/componentor the application. The deliberate exception is the foundational Base Input frame, which provides only a semantic one-pixel input border and semantic radius baseline; UI/application layers own its background, sizing, padding, typography, adornments, and richer focus style. - GPUI builder style: Keep element construction as one fluent builder chain. Express
conditions with
when,when_some,when_none, andmap; do not split a chain into a mutable temporary element followed by imperative reassignment when the builder API can express the same operation. - No
pubfields on public data types: A public struct handed across thegpui-base/application seam — a state snapshot, capability set, render context, or option set — keeps its fields private, is constructed with a builder, and is read through methods. Adding apubfield is a breaking change; adding one behind a builder is not. Setters and readers must not collide: an all-boolean type names setters after the field and readersis_<adjective>/has_<noun>, nevercan_; a type with non-boolean fields prefixes every setter withwith_and keeps the field name for readers. Value types whose fields are the definition and cannot grow (Point,Selection,Edges) are exempt. See the "Public Data Types Across the Seam" section ofdocs/ARCHITECTURE.md. - Spell
Contextout: Name a context typeComboboxTriggerContext, never…Ctx.cxis reserved for GPUI'sApp,Context<T>, andAsyncApp, soctxfor anything else reads as a competing context. A callback receiving both takes the GPUI one ascxand names the other after what it holds (trigger,state).
- Follow naming and organization patterns from existing code
- Reference macOS/Windows control API design for naming
- AI-generated code must be refactored to match project style
- Mark AI-generated portions when submitting PRs
- When creating a PR, inspect previous PR titles in the repository and match
that style. Do not blindly use conventional prefixes like
fix:orfeat:unless the existing PR title style uses them. - When a PR changes the public API of
crates/component, add a## Breaking Changessection withdiffblocks showing the old and new usage. See PR #2691 and.claude/skills/gpui-component-dev/references/pr-description.md. - Avoid
Kindas a type-name suffix. It says an enum classifies something without saying what it classifies, and carries no meaning a reader could not already infer fromenum. Name the type after what its variants are instead. KeepKindonly when no honest name covers the variant set —NodeKind's variants straddle two levels (Splitis an interior node,TabsandTilesare leaves), and every domain word for the leaf level (Pane, most of all) would misdescribeSplit; a vaguer name is better than a precise wrong one. Prefer confining such a type topub(crate). This governs new code; existingKindnames are not a rewrite target on their own, and names owned by external crates (CodeActionKind,CompletionItemKind,WindowKind) keep their upstream spelling.
The Icon element does not include SVG files by default. You need to:
- Use Lucide or other icon libraries
- Name SVG files according to the
IconNameenum definition (located incrates/component/src/icon.rs)
- GPUI: Git version from Zed repository
- Tree-sitter: For syntax highlighting
- Ropey: Rope data structure for text, and
RopeExttrait with more features. - Markdown rendering:
markdowncrate - HTML rendering:
html5ever(basic support) - Charts: Built-in chart components
- LSP:
lsp-typescrate
Uses rust-i18n crate.
- Localization files are located in
crates/component/locales/. - Only add
en,zh-CN,zh-HKby default.
-
The documentation site source is in
website/. -
Site docs have two locales: English (
website/docs/) and Chinese (website/zh-CN/docs/). -
When modifying any documentation file, always sync changes to both
enandzh-CNversions. -
docs/holds internal architecture specifications (RFC, migration status, reviews). These are single-language and are not published to the site; seedocs/README.md. -
skills/gpui-kit/references/coding-guides.mdandskills/gpui-kit-design-guides/references/design-guides.mdare verbatim copies of the Englishwebsite/docs/originals, vendored so the skills work afternpx skills addin a project that does not have this repo. After editing either guide, copy it across:cp website/docs/design-guides.md skills/gpui-kit-design-guides/references/design-guides.md cp website/docs/coding-guides.md skills/gpui-kit/references/coding-guides.md
CI fails if the copies drift. Never edit the copy directly — edit
website/docs/.
- macOS (aarch64, x86_64)
- Linux (x86_64)
- Windows (x86_64)
CI runs full test suite on each platform.
This project has custom Claude Code skills to assist with common development tasks:
- gpui-kit (
skills/) - Building applications on thegpui-kitcrate: setup, component catalog, stateless/stateful patterns, theming, GPUI mechanics (actions, async, contexts, custom elements, entities, events, focus, global state, layout,ElementId, testing), and the normative Coding Guides - gpui-kit-design-guides (
skills/) - The normative Design Guides; load before any UI, layout, interaction, or interface-copy work - gpui-component-dev (
.claude/skills/) - Contributing to gpui-component: creating new components, writing stories, writing documentation, writing PR descriptions
When working on tasks related to these areas, Claude Code will automatically use the appropriate skill to provide specialized guidance and patterns.
See .claude/COMPONENT_TEST_RULES.md for detailed testing principles:
- Simplicity First: Focus on complex logic and core functionality, avoid excessive simple tests
- Builder Pattern Testing: Every component should have a
test_*_buildertest covering the builder pattern - Complex Logic Testing: Test conditional branching, state transitions, and edge cases