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-interopdevelopment
Use when the user wants to spin up / create / launch / provision a DigitalOcean droplet (or "a remote dev box on DO") and connect to it from Codex as a remote SSH workspace.
data-ai
Search through Microsoft Teams chats or channels, triage unread or recent activity, draft follow-ups, and manage Planner tasks through connected Teams data.
tools
Motion / animation context for the `use_figma` MCP tool — animating Figma nodes via manual keyframes, animation styles, easing, and timeline duration. Load alongside figma-use whenever a task involves adding, editing, or inspecting animation on a node.
development
SwiftUI ↔ Figma translation. Use whenever the user mentions Swift, SwiftUI, iOS, iPhone, or iPad — in EITHER direction — translating a Figma design into SwiftUI (design → code), or pushing SwiftUI views / screens / tokens back into a Figma file (code → design). Triggers on phrases like 'implement this Figma design in SwiftUI', 'build this screen in Swift', 'push this SwiftUI view to Figma', 'mirror my Swift code in a Figma file', or whenever a Figma URL appears alongside `.swift` files / an `.xcodeproj`. Routes to a direction-specific reference doc; loads alongside `figma-use` for the code → design path.