Use when implementing iOS 17+ SwiftUI patterns: @Observable/@Bindable, MVVM architecture, NavigationStack, lazy loading, UIKit interop, accessibility (VoiceOver/Dynamic Type), async operations (.task/.refreshable), or migrating from ObservableObject/@StateObject.
View on GitHubjohnrogers/claude-swift-engineering
swift-engineering
plugins/swift-engineering/skills/swiftui-patterns/SKILL.md
February 5, 2026
Select agents to install to:
npx add-skill https://github.com/johnrogers/claude-swift-engineering/blob/main/plugins/swift-engineering/skills/swiftui-patterns/SKILL.md -a claude-code --skill swiftui-patternsInstallation paths:
.claude/skills/swiftui-patterns/# SwiftUI Patterns (iOS 17+)
SwiftUI 17+ removes ObservableObject boilerplate with @Observable, simplifies environment injection with @Environment, and introduces task-based async patterns. The core principle: use Apple's modern APIs instead of reactive libraries.
## Overview
## Quick Reference
| Need | Use (iOS 17+) | NOT |
|------|---------------|-----|
| Observable model | `@Observable` | `ObservableObject` |
| Published property | Regular property | `@Published` |
| Own state | `@State` | `@StateObject` |
| Passed model (binding) | `@Bindable` | `@ObservedObject` |
| Environment injection | `environment(_:)` | `environmentObject(_:)` |
| Environment access | `@Environment(Type.self)` | `@EnvironmentObject` |
| Async on appear | `.task { }` | `.onAppear { Task {} }` |
| Value change | `onChange(of:initial:_:)` | `onChange(of:perform:)` |
## Core Workflow
1. Use `@Observable` for model classes (no @Published needed)
2. Use `@State` for view-owned models, `@Bindable` for passed models
3. Use `.task { }` for async work (auto-cancels on disappear)
4. Use `NavigationStack` with `NavigationPath` for programmatic navigation
5. Apply `.accessibilityLabel()` and `.accessibilityHint()` to interactive elements
## Reference Loading Guide
**ALWAYS load reference files if there is even a small chance the content may be required.** It's better to have the context than to miss a pattern or make a mistake.
| Reference | Load When |
|-----------|-----------|
| **[Observable](references/observable.md)** | Creating new `@Observable` model classes |
| **[State Management](references/state-management.md)** | Deciding between `@State`, `@Bindable`, `@Environment` |
| **[Environment](references/environment.md)** | Injecting dependencies into view hierarchy |
| **[View Modifiers](references/view-modifiers.md)** | Using `onChange`, `task`, or iOS 17+ modifiers |
| **[Migration Guide](references/migration-guide.md)** | Updating iOS 16 code to iOS 17+ |
| **[MVVM Observable](refere