plugins/build-macos-apps/skills/swiftui-patterns/SKILL.md
Build macOS SwiftUI scenes and components with desktop patterns. Use when shaping windows, commands, toolbars, settings, split views, or inspectors.
npx skillsauth add openai/plugins swiftui-patternsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Choose a track based on your goal:
references/components-index.md.appkit-interop skill rather than forcing a shaky workaround.WindowGroup, Window, Settings, MenuBarExtra, or DocumentGroup.MenuBarExtra, use WindowGroup(..., id:) for the primary window when it should appear at launch. Treat Window(...) as a better fit for auxiliary/on-demand singleton windows; in menu-bar-heavy apps, a Window(...) scene may not present the main window automatically at launch.git rev-parse --is-inside-work-tree. If not, run git init at the project root so Codex app git-backed features are available from the start. Do not initialize a nested repo inside an existing parent checkout.script/build_and_run.sh and .codex/environments/environment.toml so the Codex app Run button works immediately. Use the exact bootstrap contract from build-run-debug and its references/run-button-bootstrap.md file rather than inventing a second variant here.Color.primary, Color.secondary, semantic foreground styles, .regularMaterial, etc.) so the app follows Light/Dark mode automatically. Do not hardcode white or light backgrounds unless the user explicitly asks for a fixed theme, and do not reach for opaque windowBackgroundColor fills for root panes by default.For any non-trivial macOS app, start with this shape instead of putting the app, all views, models, stores, services, and helpers in one Swift file:
App/<AppName>App.swift: the @main app type and AppDelegate only.Views/ContentView.swift: root layout and high-level composition only.Views/SidebarView.swift, Views/DetailView.swift, Views/ComposerView.swift, etc.: feature views named after their primary type.Models/*.swift: value models, identifiers, and selection enums.Stores/*.swift: persistence and state stores.Services/*.swift: app-server, network, process, or platform clients.Support/*.swift: small formatters, resolvers, extensions, and glue helpers.Keep files small and named after the primary type they contain. If a file starts collecting unrelated views, models, stores, networking clients, and helper extensions, split it before adding more behavior.
Before writing the full UI:
script/build_and_run.sh and .codex/environments/environment.toml separate from app source.ContentView.commands, toolbars, sidebars, inspectors, contextual menus, and searchable.MenuBarExtra item titles and action labels short and scannable. Cap visible menu item text at 30 characters; if source content is longer, truncate or summarize it before rendering and open the full content in a dedicated window or detail surface.MenuBarExtra app should still behave like a regular Dock app with a visible main window/process, install an NSApplicationDelegate via @NSApplicationDelegateAdaptor, call NSApp.setActivationPolicy(.regular) during launch, and activate the app with NSApp.activate(ignoringOtherApps: true). If the app is intentionally menu-bar-only, document that .accessory / no-Dock behavior is a deliberate product choice.NavigationSplitView sidebars or root window panes with opaque custom Color(...) or Color(nsColor: .windowBackgroundColor) fills by default. Prefer native macOS sidebar/window materials and system-provided backgrounds unless the user explicitly asks for a custom opaque surface. In sidebar-detail-inspector layouts, let the sidebar keep the standard source-list/material appearance and reserve custom backgrounds for detail or inspector content cards where needed.@SceneStorage for per-window ephemeral state and @AppStorage for durable user preferences.NavigationSplitView or a deliberate manual split layout over iOS-style stacked flows when the app benefits from always-visible structure.List(...).listStyle(.sidebar) and NavigationSplitView sidebars, prefer flat native rows with standard system selection/highlight behavior. Keep rows visually lightweight and Mail-like: at most one leading icon, one strong title line, and one optional secondary detail line in .secondary. Avoid stacked metadata rows, repeated inline utility icons, or dense multi-column status text in the sidebar. Reserve card-style and metadata-heavy surfaces for detail or inspector panes unless the user explicitly asks for a highly custom sidebar treatment.appkit-interop.For concrete sidebar row and split-view background examples, read
references/split-inspectors.md.
Use the narrowest state tool that matches the ownership model:
| Scenario | Preferred pattern |
| --- | --- |
| Local view or control state | @State |
| Child mutates parent-owned value state | @Binding |
| Root-owned reference model on macOS 14+ | @State with an @Observable type |
| Child reads or mutates an injected @Observable model | Pass it explicitly as a stored property |
| Window-scoped ephemeral selection or expansion state | @SceneStorage when practical, otherwise scene-owned @State |
| Shared user preference | @AppStorage |
| Shared app service or configuration | @Environment(Type.self) |
| Legacy reference model on older targets | @StateObject at the owner and @ObservedObject when injected |
Choose the ownership location first, then the wrapper. Do not turn simple desktop state into a view model by reflex.
references/components-index.md: entry point for scene and component guidance.references/windowing.md: choosing between WindowGroup, Window, DocumentGroup, and window-opening patterns.references/settings.md: dedicated settings scenes, SettingsLink, and preference layouts.references/commands-menus.md: command menus, keyboard shortcuts, focused values, and desktop action routing.references/split-inspectors.md: sidebars, split views, selection-driven layout, and inspectors.references/menu-bar-extra.md: menu bar extra structure and when it fits.ContentView pretending the whole app is a single screen.@main app, all views, models, stores, networking/process clients, formatters, and extensions. This is acceptable only for tiny throwaway snippets under the new-app threshold above.Window(...) scene and then expecting the main window to appear at launch. Use WindowGroup(..., id:) for the primary launch window and reserve Window(...) for auxiliary/on-demand windows..background(.white), Color.white, or a fixed light palette in a brand-new scaffold without an explicit design requirement..sidebar list, which fights native source-list density, alignment, and selection behavior unless the user explicitly asked for a bespoke visual sidebar.NavigationSplitView sidebars or root window panes with opaque custom color fills by default, instead of letting the sidebar use native source-list/material appearance and reserving custom backgrounds for actual content cards.Use references/components-index.md as the entry point. Each component reference should include:
appkit-interoptools
Top-level workflow skill for USD performance diagnosis and optimization. Use for slow loading, high memory, low FPS, or 'optimize my scene' requests; delegates auth/runtime setup to Phase 0 owners.
data-ai
Use when the user mentions MagicPath, designs, UI components, themes, canvas selections, or repo-to-canvas UI work; run magicpath-ai to search, inspect, install, or author components.
documentation
Use as the top-level router for Omniverse Realtime Viewer USD app requests and focused viewer reference documents.
tools
Turn Notion specs into implementation plans, tasks, and progress tracking; use when implementing PRDs/feature specs and creating Notion plans + tasks from them.