All skills
lassejlv avatar

/build-gpui-apps

@52f4cfd
by Lasselassejlv/skills50 stars
1

Build, scaffold, refactor, debug, review, and validate native Rust desktop applications with GPUI. Recommend GPUI Kit and ask before adopting it; use gpui_kit imports after agreement, or preserve the chosen upstream GPUI stack. Includes the merged GPUI Kit component and design skills, full application/Base/Component/Shell documentation, coding and design guides, state, actions, async, input, accessibility, motion, themes, native integration, packaging, auto updates, testing, and production delivery. Use paper-to-gpui when the primary task is faithfully translating a selected Paper.design frame into an existing view.

Use this Skill: https://skilld.dev/gh/lassejlv/skills/build-gpui-apps

This session only. Nothing lands on disk.

referencesgpui-kitv0.7.0.md

GPUI Kit 0.7.0: migration and capabilities

Read this when upgrading to 0.7.0 or choosing its new APIs. Audited on 2026-10-01 against the release notes, tag commit 0c830f4d257e69fdd17200650533ab4ca9a40cc0, manifest, and facade source. The complete 183-page documentation bundle supplies the full API guides; this reference identifies upgrade decisions and routes them.

Version and framework choice

  • Kit 0.7.0 pins its GPUI snapshot to =0.3.7. Keep the related snapshot packages aligned through Kit; its independent gpui-pre-reqwest fork uses =0.12.15. Do not override GPUI separately to obtain a newer API.
  • Application imports remain gpui_kit::*, gpui_kit::component, gpui_kit::base, gpui_kit::assets, and gpui_kit::platform. gpui-shell remains separate for JavaScript extension hosts.
  • Preserve the framework choice policy: recommend Kit and obtain agreement before adoption/migration. An authorized upgrade of an established Kit app does not reopen that choice.
  • Some refreshed website examples still specify 0.6/0.6.5; they do not override the 0.7.0 release manifest. Confirm signatures in the selected tag and target lockfile instead of combining examples from incompatible versions.
  • Upstream advertises release docs at /versions/<tag> and development docs at /versions/main. Verify availability before relying on them; tested 0.7.0 installation Markdown URLs returned 404 during this audit.

New components and changed capabilities

Task Read 0.7.0 contract to preserve
Command rows Toolbar Toolbar/ToolbarGroup retain source order and accessible groups. child/children accept sized controls; content/contents preserve custom dimensions. Buttons become compact ghost controls. Small is the default; Large resolves to Medium. Left/Right wraps through enabled controls; disabling navigation does not disable them.
Structured questions Questionnaire One retained QuestionnaireState owns single/multiple-choice and freeform answers, validation, optional skip, keyboard navigation, progress, and submission. Compose its parts around that owner.
Time and date editing TimeField, DatePicker TimePrecision::{Minute, Second} and HourCycle::{H23, H12} configure segments. DatePicker exposes time_precision, hour_cycle, default_time, date_time/set_date_time, and date/time presets. Time-enabled single mode emits Change for each edit while staying open; range mode remains date-only.
Mentions and command tokens Input Opt-in InlineToken, insertion/replacement, InputContent, and token activation retain atomic navigation/deletion/undo while values and clipboard stay plain text. Rust ranges use UTF-8 bytes; Shell ranges use UTF-16 offsets. Tokens are unavailable in Editor, NumberInput, password, and masked inputs.
Editor decorations and menus Input InputExtras::range_decorations uses UTF-8 byte ranges. Textarea supports sizing. InputState::context_menu(false) disables the entire menu, including a custom builder; leave it enabled for custom menus.
Markdown selection/search TextView, Base TextView selected_source_range() refers to original Markdown bytes. Search rendered_text() for rendered-copy byte ranges, apply RangeHighlight with set_range_highlights, and reveal with reveal_range/on_reveal. Highlights are Markdown-only; reveal is best effort. Do not mix the two offset spaces.
Live and custom charts Charts, Base plot Fixed y_domain, reserved point_count/band_count, axes/grids/reference lines, labels, and tooltip callbacks support streaming series. chart.grid separates grid color from borders. Use distinct IDs for charts sharing a construction site; interactive(false) removes hover work. Base primitives need no Component dependency.
Dock movement and resizing Dock, Base Dock Nested moves preserve ownership. Close buttons are opt-in through DockSkin::set_close_button_visible. Bottom docks can close/reopen in one drag; finish custom resizing with DockContext::end_resize and avoid persisting transient sizes below minimum.
Theme changes Theme Prefer Theme::update(cx, ...) to reconcile colors, gradients, Base projection, fonts, and window refresh. global_mut/sync_base remain available for deliberate manual synchronization.
Forms and settings Form, Settings, GroupBox Form styling applies; hidden fields are not built or laid out. Group footers live outside their surface; per-group variants override Settings defaults. Cross-page group selection scrolls to its target.
Attachments and chat Attachment, Message, Marker Remove/retry/progress/tooltip controls require attachment identity; progress uses 0–100. Group scroll tracking and edge fades are available. Message has stable id/role and inherits content typography; Marker has Start/Center/End alignment.
Accessibility and popups Switch, Sidebar, List, Popover, Dialog Use exposed labels, focus rings, and explicit tab stops. Popover trigger styling affects its real geometry; Selectable::open distinguishes popup openness from selection. Dialog button properties merge supplied fields; AlertDialog supports text/variant customization.
Script host integration Shell state, Host API, Capabilities Inline tokens and TimeField are exposed to scripts. Retained state can expose StateMethodDescriptor through StateDescriptor::with_methods; token subtrees are frame-owned. Remote TextView images require HTTP GET grants for the original URL and every redirect.
Distribution and framework manual Packaging, Auto Update, Images, complete index Use the expanded ownership, focus, input, testing, and platform guides. Bind keys before set_menus; a focus handle needs an explicit Tab-stop contract. Packaging/updater ownership stays with the application.
Browser and mobile hosts WebView, WebAssembly, Mobile WebView is experimental on macOS/Windows with an unfinished Linux path. Browser examples use one top-level canvas/window. Mobile validation covers a limited chat subset; its pinned example uses GPUI 0.3.4 and needs platform/renderer alignment before using Kit 0.7.0's 0.3.7 snapshot.

Window hosting migration

Read Root and Window. Call gpui_kit::init(cx) before creating windows. The verified helper returns Result<(AnyWindowHandle, Entity<V>)> and supplies one Base-owned Root:

let (window_handle, content) =
    gpui_kit::open_window(options, cx, |window, cx| {
        build_content(window, cx) // Entity<V>, not Entity<Root>
    })?;

In async work, call it within cx.update. Retain the content entity when application state needs it. Quit/close actions and unsaved-change flows remain application-owned.

  • Delete Root::render_dialog_layer, Root::render_sheet_layer, and Root::render_notification_layer calls: those APIs are removed and Root mounts the layers itself. Do not wrap the helper's content in another Root.
  • Move old root-level dialog/sheet/notification operations to Component WindowExt: window.open_dialog(cx, build), window.close_dialog(cx), window.close_all_dialogs(cx), window.open_sheet_at(placement, cx, build), window.close_sheet(cx), and the corresponding notification operations.
  • Use Base TextSelection::{selected_text, has_selection, clear, end} for old window/root selection helpers. Use window_border() with WindowOptions instead of old Root::bordered/window_shadow_size helpers. Verify the actual imports and arguments in the locked source.
  • Custom design systems can register RootPlugin factories before opening windows. Plugins run in registration order and are per-window; replacing a factory affects future windows and does not retrofit existing roots.
  • Explicit low-level cx.open_window remains possible with one correctly constructed Root. Cargo feature unification does not select a different root type. Do not migrate an older app's overlays without checking its source.

Breaking changes

Review every row against actual callers; many changes affect behavior or appearance even when the app still compiles.

Affected API/behavior Required adaptation
Custom plot location and element Prefer gpui_kit::base::plot; Component paths remain re-exported. IntoPlot derives now produce PlotElement<Self> instead of implementing Element directly. Hidden plot::tooltip::track_hover is removed.
Plot curves, scales, and bounds Replace StrokeStyle/stroke_style with Curve/curve. Scale ranges are arrays, domains accept iterators, and generic values use PlotValue instead of the hidden Sealed bound. least_index becomes nearest_index; least_index_with_domain is removed. Grid x/y accept iterators.
Plot geometry and construction Configure Arc radii on the Arc before paint/contains. Base ScaleBand has no implicit 30px cap; set max_band_width when needed. PlotAxis::default() now shows the x-axis line, matching new(). Base Theme literals need plot.
Non-exhaustive plot types Use constructors for TooltipState, AxisText, label::Text, ArcData, StackPoint, StackSeries, SankeyLink, SankeyNodeLayout, SankeyLinkLayout, and SankeyGraph.
Deprecated plot aliases Prefer axis_gutter, dot_fill, dot_stroke, and progress over AXIS_GAP, dot_fill_color, dot_stroke_color, and PlotHover::focus/Tooltip::focus. Existing styled chart curve builders are unchanged.
DatePicker values DatePickerEvent::Change carries DateTime, not Date. Date-only consumers use value.date(). Exhaustive DateRangePresetValue matches handle its DateTime variant. format keeps its signature.
Base headings Replace with_heading_base_font_size, heading_base_font_size, with_heading_font_size, and heading_font_size with with_heading/heading and a level-aware StyleRefinement. Component retains compatibility builders/fields.
DataTable selection Match TableSelection::{None, Row, Column, Cell} or use the active positional getter. A selected cell's row comes from selected_cell(), not selected_row(). Inactive selection history belongs to the application.
BarChart ticks value_tick_count(n) now counts ticks rather than intervals. Increment an explicit old count by one to keep its appearance. The new default is five ticks, preserving the old four-interval layout.
Tooltip motion Tooltip springs its own crosshair/dots. Remove a custom spring or choose glide(false); supply full dot halo sizes because Tooltip applies hover progress.
Shell document images Grant GET for the URL and every redirect. Non-HTTP(S) sources, including data URLs, are refused; HTTPS downgrades are rejected. App asset image(path) is unchanged.
Select dismissal Closing an open menu emits DismissEvent. Confirmation emits Confirm then DismissEvent; opening or closing an already-closed menu does not dismiss. Check callbacks that would now run twice.
Popover anchors LeftCenter puts the popup to the trigger's right; RightCenter puts it to the left, both vertically centered. These replace the old top-left fallback; top/bottom anchors retain their placement.
Disabled Accordion items An individually disabled item stays disabled. Explicitly enable it if expansion was intended.
Message typography Bare MessageContent inherits caller typography instead of imposing text_sm/1.25. Explicitly style content that needs the old appearance. Header/footer styles remain local.
Base Dialog Normal-flow popups center by default. items_start().justify_start() restores top-left hosting when needed. Popup presses no longer reach the backdrop; size popup parts to their content. Component Dialog placement is unchanged.
Base single-line Input Text fills/centers vertically in its frame. Use a one-line-height frame for the former top-aligned appearance. Multiline and Component layout are unchanged.
Accordion lifetime / Pagination Accordion content unmounts after its closing spring settles; store durable state in entities. Reduced motion keeps content mounted. Pagination ellipsis menus show only the nearest 100 hidden choices; farther pages need successive menus.
Field visibility / Attachment Field::visible(false) now hides the field. Review attachment chip sizing, radius, status overlays, and failure colors against the new defaults.
Chart labels and duplicate values Line/Area charts place duplicate x values by their own indices. Labeled vertical bars reserve slightly more top space (bars are 2px shorter). Pie tooltip labels are configured separately from leader-line labels.

Validation for an upgrade

Record old/new versions, feature changes, lockfile, and release source. Build and test the owning crate using the project versioning workflow. Exercise affected UI contracts: one Root per window, overlay stacking and focus restoration, date-only/time editing events, selection transitions, popup confirmation/dismissal, close/reopen state, chart geometry/hover, theme changes, and script image permission failures as applicable.

Include Unicode token/range tests when touching editing: Rust UTF-8 bytes, Shell UTF-16 offsets, rendered Markdown copy offsets, and original source offsets are distinct contracts. Cover IME, undo, disabled focus, and stale async completions in the real input workflow. New input/text/chart caching and resource-release fixes do not establish performance in the downstream app; measure relevant large-data, streaming, hover, and close/disposal paths.

Launch the real app on each claimed platform and compare the affected visual states. This skill refresh does not claim to compile or run a Kit consumer.

Credit: GPUI Kit's release notes, tagged source, and official documentation. This is an adapted migration summary and documentation router. Eligible upstream documentation prose uses CC BY 4.0; software/code examples use Apache-2.0.

Source: SKILL.md on GitHub

No alerts3d3 checks · Risk SAFE
  • Gen Agent Trust Hub3d

    The skill provides comprehensive documentation and reference material for building native desktop applications using Rust and GPUI. No security risks, prompt injections, or malicious behaviors were identified. External dependencies originate from reputable organizations in the Rust ecosystem.

  • Socket3d

    No alerts

  • Snyk3d

    Risk: LOW · No issues

Signed by skilld at 52f4cfd. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 4 days ago

README badge

README badge for lassejlv/skills/build-gpui-apps