
The swiftui-expert-skill enables developers to write, review, and improve SwiftUI code by providing guidance on state management, view composition, performance optimization, and adoption of modern APIs including iOS 26+ Liquid Glass features. It serves Swift developers building new SwiftUI features or refactoring existing code who need to follow Apple's best practices while avoiding deprecated APIs and ensuring optimal performance. The skill solves the problem of navigating SwiftUI's evolving API surface and architectural patterns by offering specific, opinionated guidance backed by reference documentation on topics like animation, accessibility, list patterns, and version-specific feature gating.
$ npx -y skills add avdlee/swiftui-agent-skill --skill swiftui-expert-skill --agent claude-codeInstalls into .claude/skills of the current project.
View type as an invalidation boundary: give it only the data it reads and keep frequently changing dependencies close to the smallest affected subtreereferences/latest-apis.md when writing, reviewing, or migrating API usage; look up only the APIs relevant to the taskreferences/soft-deprecation.md)references/liquid-glass.md)#available gating with sensible fallbacks for version-specific APIsreferences/latest-apis.md); replace hard-deprecated APIs, and flag soft-deprecated APIs without rewriting them unless the user asked to migrate#available gating and fallback paths for version-specific featuresreferences/latest-apis.md; flag soft-deprecated APIs and do not rewrite them during feature workUIImage(data:) is encountered (optional optimization, see references/image-optimization.md)Button for all tappable elements; add accessibility grouping and labels#available and provide fallbacksTrigger when the user asks to "record a trace", "profile the app", "capture a session", etc. Full reference: references/trace-recording.md.
python3 "${SKILL_DIR}/scripts/record_trace.py" --list-devices
SwiftUI template populates the SwiftUI lane on any real device: a physical iOS/iPadOS device or the host Mac. The only exception is the iOS Simulator, where the SwiftUI lane comes back empty — switch to --template "Time Profiler" in that case (still gives Time Profiler + Hangs + Animation Hitches). Always check --list-devices: simulators kind → Time Profiler; devices kind (real devices and the host Mac) → default SwiftUI. Full decision table in references/trace-recording.md.python3 "${SKILL_DIR}/scripts/record_trace.py" \
--device "<name|udid>" --attach "<AppName>" \
--stop-file /tmp/stop-trace --output ~/Desktop/session.trace
For interactive sessions, just tell the user to press Ctrl+C when done.touch /tmp/stop-trace. The script cleanly SIGINTs xctrace and waits up to 60s for finalisation..trace provided)Trigger whenever the user's request references a .trace file. A target SwiftUI source file is optional — if given, cite specific lines; if not, recommend where to look based on view names and symbols the trace already reveals.
Full reference: references/trace-analysis.md. Summary of the composition pattern:
# Find a log that marks the start/end of the region of interest:
python3 "${SKILL_DIR}/scripts/analyze_trace.py" --trace <path> \
--list-logs --log-message-contains "loaded feed" --log-limit 5
# Or list os_signpost intervals (paired begin/end), filterable by name:
python3 "${SKILL_DIR}/scripts/analyze_trace.py" --trace <path> \
--list-signposts --signpost-name-contains "ImageDecode"
Both modes accept --window START_MS:END_MS to scope discovery. Pick the time_ms (for logs) or start_ms/end_ms (for signposts) that match the user's description. Build a window like --window 10400:11700.--window):
python3 "${SKILL_DIR}/scripts/analyze_trace.py" --trace <path> \
--json-only --top 10 [--window START_MS:END_MS]
references/trace-analysis.md — key diagnostics:
main_running_coverage_pct inside each correlation (<25% = blocked; ≥75% = CPU-bound).swiftui-causes.top_sources reveals why updates keep happening — high-edge-count sources like UserDefaultObserver.send() or wide EnvironmentWriter entries are structural invalidation bugs. Fixing one often collapses many downstream hot views.--fanin-for "<view name>" to get the ranked list of source nodes driving the updates.Consult the reference file for each topic relevant to the current task:
| Topic | Reference |
|---|---|
| State management | references/state-management.md |
Environment and @Entry | references/environment-patterns.md |
| View composition | references/view-structure.md |
| View modifiers and identity | references/modifier-patterns.md |
| Performance | references/performance-patterns.md |
| Lists and ForEach | references/list-patterns.md |
| Resizable layout, safe areas, two-column reflow, foldable grids, arrangements, and reserved regions | references/layout-best-practices.md |
| iPhone Duo, foldable, or large-display screens (read first to choose the technique) | references/iphone-duo.md |
Sheets, navigation, NavigationSplitView on large displays, and tab bar/sidebar (sidebarAdaptable) | references/sheet-navigation-patterns.md |
| ScrollView, scroll position, and scroll geometry | references/scroll-patterns.md |
| Focus management | references/focus-patterns.md |
| Animations (basics) | references/animation-basics.md |
| Animations (transitions) | references/animation-transitions.md |
| Animations (advanced) | references/animation-advanced.md |
| Accessibility | references/accessibility-patterns.md |
| Swift Charts | references/charts.md |
| Charts accessibility | references/charts-accessibility.md |
| Image optimization and display scale | references/image-optimization.md |
| Toolbars | references/toolbar-patterns.md |
| Document-based apps | references/document-apps.md |
| WebKit | references/webkit-integration.md |
| Styled text editing | references/styled-text-editing.md |
| Liquid Glass (iOS 26+) | references/liquid-glass.md |
| macOS scenes | references/macos-scenes.md |
| macOS window styling | references/macos-window-styling.md |
| macOS views | references/macos-views.md |
| Text patterns | references/text-patterns.md |
| Localization | references/localization.md |
| Deprecated API lookup | references/latest-apis.md |
| Handling soft-deprecated APIs | references/soft-deprecation.md |
| Previews | references/previews.md |
| Instruments trace analysis | references/trace-analysis.md |
| Instruments trace recording | references/trace-recording.md |
These are hard rules -- violations are always bugs:
@State properties are private@Binding only where a child modifies parent state@State/@StateObject; intentional state seeds are documented as one-time@StateObject for view-owned objects; @ObservedObject for injected@State with @Observable; @Bindable for injected observables needing bindingsForEach uses stable identity (never .indices/\.offset; id outlives the view and isn't derived from mutable content)ForEach element; List rows are unary@Environment/@FocusedValue keys@Entry default values are stable (no Model()/Date()/UUID() expressions)@Environment(\.displayScale), not global screen stateGeometryProxy.safeAreaInsets.animation(_:value:) always includes the value parameter@FocusState properties are private@FocusState writes inside tap gesture handlers on .focusable() views#available and have sensible fallbacksimport Charts present in files using chart typesSponsors