Swiftui expert skill
Write, review and improve SwiftUI: state, composition, performance, animations, accessibility and iOS 26 Liquid Glass - Agent Skill
npx -y skills add SwiftyJourney/swiftui-expert-skillAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Write, review, or improve SwiftUI code following best practices for state management, view composition, performance, accessibility, and modern APIs. Use when building SwiftUI features, refactoring views, reviewing code quality, or adopting modern SwiftUI patterns.
SKILL.md
11.9 KB, as published. Nobody here has run it
SwiftUI Expert Skill
Agent Behavior Contract
When this skill is active, follow these rules strictly:
- Focus on facts and best practices, not architecture — defer architectural decisions (MVVM, MVC, VIPER, Clean Architecture, Coordinator) to
ios-architecture-expert. - Always prefer
@ObservableoverObservableObjectfor new code. Mark@Observableclasses with@MainActorunless using default actor isolation. - Never use
applyIfor generic conditional modifier helpers — they break view identity. - Prefer modifiers over conditional views for state changes (preserves structural identity).
- Use modern APIs over deprecated equivalents — see
references/modern-apis.md. - Lead with corrected/improved code when reviewing; explain why a pattern is better (diffing, thread safety, API correctness).
- Use "prefer"/"avoid" for recommendations; "always"/"never" only for API correctness.
- Respond in the same language the user writes in — default to English when uncertain.
- Adopt Liquid Glass only when explicitly requested — glass is for controls and navigation only (HIG).
- Gate iOS 26+ features with
#availableand provide fallbacks.
Diagnostic Table
| Symptom | First check | Smallest fix | Deep dive |
|---|---|---|---|
| Wrong property wrapper chosen | Ownership direction | Match wrapper to data flow | references/state-management.md |
| View re-renders too often | Dependency graph | Narrow state dependencies | references/performance-patterns.md |
| Deprecated API warning | API replacement table | Swap to modern equivalent | references/modern-apis.md |
| View body is 200+ lines | View extraction rules | Extract struct subviews | references/view-composition.md |
| ForEach flickers or reorders | Identity stability | Use stable Identifiable ID | references/list-patterns.md |
| Animation is janky or missing | Implicit vs explicit | Match animation to state change site | references/animation-basics.md |
| Glass effect on wrong layer | HIG compliance | Glass on controls only, not content | references/liquid-glass.md |
| Custom control lacks accessibility | Semantic components | Use Button/Label or accessibilityRepresentation | references/accessibility-patterns.md |
| Tap/gesture not firing inside a scroll or list | Gesture precedence | Use highPriorityGesture/simultaneousGesture | references/gestures.md |
| Async load leaks, re-fires, or janks the UI | Task lifecycle & isolation | .task/.task(id:); offload heavy work with @concurrent | references/data-loading-and-tasks.md |
| Need a layout stacks/grids can't express | Layout negotiation | Conform to the Layout protocol | references/layout-protocol.md |
| App body won't compile or state leaks across windows | Scene structure | App body returns some Scene; WindowGroup is per-window | references/app-lifecycle-and-scenes.md |
| Persisting settings or restoring per-scene state | Persistence mechanism | @AppStorage/@SceneStorage/SwiftData/PreferenceKey | references/data-persistence.md |
Quick Summary
| Area | Key Principle | Reference |
|---|---|---|
| State Management | @Observable + @MainActor; @State for owned, @Binding for child-modifies-parent | references/state-management.md |
| View Composition | Small single-responsibility views; extract structs, not @ViewBuilder functions | references/view-composition.md |
| Modern APIs | foregroundStyle, clipShape, NavigationStack, Tab, Button over onTapGesture | references/modern-apis.md |
| Performance | Cheap inits, pure body, narrow dependencies, stable ForEach identity | references/performance-patterns.md |
| Animations | withAnimation for events, .animation(_:value:) for reactive, transforms over layout | references/animation-basics.md |
| Accessibility | Semantic fonts/styles, @ScaledMetric, accessibilityRepresentation for custom controls | references/accessibility-patterns.md |
| Liquid Glass | Controls/navigation only (HIG); Glass.regular default; GlassEffectContainer for groups | references/liquid-glass.md |
| Data Loading | .task over .onAppear{Task{}}; .task(id:) for fetch-on-change; @concurrent to offload heavy work | references/data-loading-and-tasks.md |
| Gestures | @GestureState auto-reset; gesture precedence (highPriority/simultaneous); modern MagnifyGesture/RotateGesture | references/gestures.md |
| Layout | Parent proposes, child chooses, parent positions; custom Layout for bespoke arrangements | references/layout-protocol.md |
| App Lifecycle | App body returns some Scene; WindowGroup per-window state; scenePhase read-site semantics | references/app-lifecycle-and-scenes.md |
| Persistence | @AppStorage (global), @SceneStorage (per-scene), SwiftData wiring, PreferenceKey (child→parent) | references/data-persistence.md |
Quick Reference
Property Wrapper Selection
| Wrapper | Use When |
|---|---|
@State | Internal view state (must be private), or owned @Observable class |
@Binding | Child modifies parent's state |
@Bindable | Injected @Observable needing bindings |
let | Read-only value from parent |
var | Read-only value watched via .onChange() |
Full guide including legacy wrappers: state-management.md
Modern API Replacements
| Deprecated | Modern Alternative |
|---|---|
foregroundColor() | foregroundStyle() |
cornerRadius() | clipShape(.rect(cornerRadius:)) |
tabItem() | Tab API (iOS 18+) |
onTapGesture() | Button (unless need location/count) |
NavigationView | NavigationStack |
onChange(of:) { value in } | onChange(of:) { old, new in } or onChange(of:) { } |
GeometryReader | containerRelativeFrame() or visualEffect() |
MagnificationGesture | MagnifyGesture |
RotationGesture | RotateGesture |
Full table: modern-apis.md
Workflow Decision Tree
1) Review existing SwiftUI code
- Check property wrapper usage ->
references/state-management.md - Verify modern API usage ->
references/modern-apis.md - Verify view composition and extraction ->
references/view-composition.md - Check performance patterns ->
references/performance-patterns.md - Inspect accessibility and Liquid Glass ->
references/accessibility-patterns.md,references/liquid-glass.md
2) Improve existing SwiftUI code
- Audit state management (prefer
@ObservableoverObservableObject) ->references/state-management.md - Replace deprecated APIs ->
references/modern-apis.md - Extract complex views into subviews ->
references/view-composition.md - Optimize hot paths and list identity ->
references/performance-patterns.md,references/list-patterns.md - Improve animations and accessibility ->
references/animation-basics.md,references/accessibility-patterns.md
3) Implement new SwiftUI feature
- Design data flow first: owned vs injected state ->
references/state-management.md - Use modern APIs and
@Observable->references/modern-apis.md - Structure views for optimal diffing ->
references/view-composition.md - Apply correct animation patterns ->
references/animation-basics.md,references/animation-advanced.md - Add accessibility and glass effects (if requested) ->
references/accessibility-patterns.md,references/liquid-glass.md
Guardrails
- Do not enforce specific architectures (MVVM, MVC, VIPER) — defer to
ios-architecture-expert - Do not use
applyIfor conditional modifier helpers that break view identity - Do not declare passed values as
@Stateor@StateObject— they only accept initial values - Do not create objects or start Tasks in view initializers or
body - Do not use
.indicesfor ForEach identity with dynamic content - Do not apply glass effects to content layer views — glass is for controls and navigation only (HIG)
- Do not use
AnyViewin list rows - Do not use
GeometryReaderwhencontainerRelativeFrame(),onGeometryChange, orvisualEffectsuffice
Verification Checklist
When implementing or reviewing SwiftUI code:
- Property wrappers match ownership direction (
@Stateprivate,@Bindingfor modification,@Observablefor shared) - No deprecated APIs (
foregroundColor,cornerRadius,NavigationView,tabItem) - View body is pure — no side effects, no Task creation, no object allocation
- Complex views extracted into struct subviews (not
@ViewBuilderfunctions) - ForEach uses stable
Identifiableidentity (never.indices) - Animations use value parameter or
withAnimation(no deprecated parameterless.animation()) - Accessibility: semantic fonts,
@ScaledMetric,ButtonoveronTapGesture - Liquid Glass (if present):
#availablegated, controls-only,GlassEffectContainerfor groups - No
applyIf, no conditional modifier helpers, no if/else for style changes - Views work in any context (no hardcoded sizes, no
UIScreen.main.bounds)
Reference Router
Open the smallest reference that matches the question:
- State & Data Flow
- state-management.md — property wrappers, data flow, when to use a ViewModel
- data-persistence.md —
@AppStorage,@SceneStorage, SwiftData wiring,PreferenceKey - data-loading-and-tasks.md —
.task/.task(id:)entry points,@concurrentoffloading, cancellation
- View Structure & Layout
- view-composition.md — view extraction, styles, specialized views, reusability
- list-patterns.md — ForEach identity, stability, list best practices
- layout-protocol.md — layout negotiation, custom
Layout, alignment guides
- Modern APIs & Navigation
- modern-apis.md — modern API usage and deprecated replacements
- navigation-patterns.md — NavigationStack, deep linking, programmatic navigation
- scroll-patterns.md — ScrollView patterns and programmatic scrolling
- text-formatting.md — modern text formatting and string operations
- App Structure
- app-lifecycle-and-scenes.md — App protocol, scenes,
WindowGroup,scenePhase
- app-lifecycle-and-scenes.md — App protocol, scenes,
- Performance & Optimization
- performance-patterns.md — optimization techniques and anti-patterns
- image-optimization.md — AsyncImage, image downsampling
- Animation & Interaction
- animation-basics.md — core concepts, implicit/explicit animations
- animation-transitions.md — transitions, custom transitions, Animatable
- animation-advanced.md — transactions, phase/keyframe, completion handlers
- gestures.md — gesture types,
@GestureState, composition & precedence
- Accessibility & Platform
- accessibility-patterns.md — semantic styling, adaptive spacing, VoiceOver
- liquid-glass.md — iOS 26+ Liquid Glass API and HIG guidance