Awesome-omni-skill gpui
GPUI UI framework best practices for building desktop applications. Use when writing GPUI code, creating UI components, handling state/events, async tasks, animations, lists, forms, testing, or working with Zed-style Rust GUI code.
install
source · Clone the upstream repo
git clone https://github.com/diegosouzapw/awesome-omni-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/gpui-justjavac" ~/.claude/skills/diegosouzapw-awesome-omni-skill-gpui && rm -rf "$T"
manifest:
skills/development/gpui-justjavac/SKILL.mdsource content
GPUI Best Practices
Comprehensive guide for building desktop applications with GPUI, the UI framework powering Zed editor. Contains 40+ rules across 8 categories, prioritized by impact.
When to Apply
Reference these guidelines when:
- Writing new GPUI views or components
- Implementing state management with Entity
- Handling events and keyboard shortcuts
- Working with async tasks and background work
- Building forms, lists, or dialogs
- Styling components with Tailwind-like API
- Testing GPUI applications
Rule Categories by Priority
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | Core Concepts | CRITICAL | |
| 2 | Rendering | CRITICAL | |
| 3 | State Management | HIGH | |
| 4 | Event Handling | HIGH | |
| 5 | Async & Concurrency | MEDIUM-HIGH | |
| 6 | Styling | MEDIUM | |
| 7 | Components | MEDIUM | |
| 8 | Anti-patterns | CRITICAL | |
Quick Reference
1. Core Concepts (CRITICAL)
- Understand GPUI's single ownership modelcore-ownership-model
- Use read/update/observe/subscribe correctlycore-entity-operations
- Use WeakEntity to break circular referencescore-weak-entity
- Know when to use App, Context<T>, AsyncAppcore-context-types
2. Rendering (CRITICAL)
- Choose Render for stateful, RenderOnce for componentsrender-render-vs-renderonce
- Build element trees with div() and method chainingrender-element-composition
- Use .when() and .when_some() for conditional stylingrender-conditional
- Use SharedString to avoid string copyingrender-shared-string
- Design components with builder patternrender-builder-pattern
3. State Management (HIGH)
- Always call cx.notify() after state changesstate-notify
- Use cx.observe() to react to Entity changesstate-observe
- Use cx.subscribe() for typed eventsstate-subscribe
- Use Global trait for app-wide statestate-global
- Use window.use_keyed_state() for persistent statestate-keyed-state
4. Event Handling (HIGH)
- Define and register actions for keyboard shortcutsevent-actions
- Use cx.listener() for view-bound event handlersevent-listener
- Manage focus with FocusHandle and key_contextevent-focus
- Understand event bubbling and stop_propagationevent-propagation
5. Async & Concurrency (MEDIUM-HIGH)
- Store or detach tasks to prevent cancellationasync-task-lifecycle
- Implement debounce with timer + task replacementasync-debounce
- Use background_spawn for CPU-intensive workasync-background-spawn
- Use WeakEntity for safe cross-await accessasync-weak-entity
- Use .log_err() and .detach_and_log_err()async-error-handling
6. Styling (MEDIUM)
- Use h_flex() and v_flex() for layoutsstyle-flexbox
- Always use cx.theme() for colorsstyle-theme-colors
- Use DynamicSpacing for responsive spacingstyle-spacing
- Use elevation system for layered surfacesstyle-elevation
7. Components (MEDIUM)
- Prefer RenderOnce with #[derive(IntoElement)]comp-stateless
- Implement Disableable, Selectable, Sizable traitscomp-traits
- Add focus ring for accessibilitycomp-focus-ring
- Use WindowExt for dialog managementcomp-dialog
- Use variant enums for component stylescomp-variant
8. Anti-patterns (CRITICAL)
- Never silently discard errors with let _ =anti-silent-error
- Never drop Task without storing or detachinganti-drop-task
- Always detach or store subscriptionsanti-drop-subscription
- Avoid Entity cycles, use WeakEntityanti-circular-reference
- Never forget cx.notify() after state changesanti-missing-notify
- Avoid unwrap(), use ? or explicit handlinganti-unwrap
Architecture Overview
┌─────────────────────────────────────────────────────────┐ │ Application (App) │ │ (Single owner of all Entities) │ └─────────────────────────────────────────────────────────┘ │ ┌───────────────────┼───────────────────┐ │ │ │ ┌───────────┐ ┌───────────┐ ┌──────────┐ │ Entity<A> │ │ Entity<B> │ │ Global<C>│ └───────────┘ └───────────┘ └──────────┘ │ │ │ │ read/update │ read/update │ via App │ via Context<A> │ via Context<B> │ │ ┌─────────────────────────────────────────────────┐ │ UI Rendering (Render trait) │ │ Each frame: fn render(&mut self, ...) │ │ Returns: impl IntoElement (Element tree) │ └─────────────────────────────────────────────────┘ │ ├─ observe() → changes trigger render ├─ subscribe() → events trigger reactions ├─ notify() → signal changes └─ emit() → send typed events
How to Use
Read individual rule files for detailed explanations and code examples:
rules/core-ownership-model.md rules/render-render-vs-renderonce.md rules/anti-silent-error.md
Each rule file contains:
- Brief explanation of why it matters
- Incorrect code example with explanation
- Correct code example with explanation
- Additional context and references