Opinionated architecture enforcement for SwiftUI clinic-style apps. This skill aligns to the iOS 26 / Swift 6.2 clinic architecture: modular MVVM-C in local SPM packages, concrete coordinators and route shells in the App target, pure Domain protocols, and Data as the only I/O layer.
Feature modules import
Domain
+
DesignSystem
only. Features never import
Data
or other features. App target is the only convergence point.
Clinic Architecture Contract (iOS 26 / Swift 6.2)
All guidance in this skill assumes the clinic modular MVVM-C architecture:
Feature modules import
Domain
+
DesignSystem
only (never
Data
, never sibling features)
App target is the convergence point and owns
DependencyContainer
, concrete coordinators, and Route Shell wiring
Domain
stays pure Swift and defines models plus repository,
*Coordinating
,
ErrorRouting
, and
AppError
contracts
Data
owns SwiftData/network/sync/retry/background I/O and implements Domain protocols
Read/write flow defaults to stale-while-revalidate reads and optimistic queued writes
ViewModels call repository protocols directly (no default use-case/interactor layer)
When to Apply
Reference these guidelines when:
Building or refactoring feature modules under local SPM packages
Wiring coordinators, route shells, and dependency container factories
Defining Domain protocols for repositories, coordinators, and error routing
Enforcing Data-only ownership of networking, persistence, and sync
Reviewing stale-while-revalidate reads and optimistic queued writes
Non-Negotiable Constraints (iOS 26 / Swift 6.2)
@Observable
for ViewModels/coordinators,
ObservableObject
/
@Published
never
No dedicated use-case/interactor layer: ViewModels call Domain repository protocols directly
Coordinator protocols live in Domain; concrete coordinators own
NavigationPath
in App target
Route shells live in App target and own
.navigationDestination
mapping
AppError
+
ErrorRouting
drive presentation policy; ViewModels do not hardcode global error UI
SwiftData / URLSession / retry / sync queue logic stays in Data package only
Rule Categories by Priority
Priority
Category
Impact
Prefix
Rules
1
View Identity & Diffing
CRITICAL
diff-
6
2
State Architecture
CRITICAL
state-
7
3
View Composition
HIGH
view-
6
4
Navigation & Coordination
HIGH
nav-
5
5
Layer Architecture
HIGH
layer-
6
6
Dependency Injection
MEDIUM-HIGH
di-
4
7
List & Collection Performance
MEDIUM
list-
4
8
Async & Data Flow
MEDIUM
data-
5
Quick Reference
1. View Identity & Diffing (CRITICAL)
diff-equatable-views
- Apply @Equatable macro to every SwiftUI view
diff-closure-skip
- Use @SkipEquatable for closure/handler properties
diff-reference-types
- Never store reference types without Equatable conformance
diff-identity-stability
- Use stable O(1) identifiers in ForEach
diff-avoid-anyview
- Never use AnyView — use @ViewBuilder or generics
diff-printchanges-debug
- Use _printChanges() to diagnose unnecessary re-renders
2. State Architecture (CRITICAL)
state-observable-class
- Use @Observable classes for all ViewModels
state-ownership
- @State for owned data, plain property for injected data
state-single-source
- One source of truth per piece of state
state-scoped-observation
- Leverage @Observable property-level tracking
state-binding-minimal
- Pass @Binding only for two-way data flow
state-environment-global
- Use @Environment for app-wide shared dependencies
state-no-published
- Never use @Published or ObservableObject
3. View Composition (HIGH)
view-body-complexity
- Maximum 10 nodes in view body
view-extract-subviews
- Extract computed properties/helpers into separate View structs
view-no-logic-in-body
- Zero business logic in body
view-minimal-dependencies
- Pass only needed properties, not entire models
view-viewbuilder-composition
- Use @ViewBuilder for conditional composition
view-no-init-sideeffects
- Never perform work in View init
4. Navigation & Coordination (HIGH)
nav-coordinator-pattern
- Every feature has a coordinator owning NavigationStack
nav-routes-enum
- Define all routes as a Hashable enum
nav-deeplink-support
- Coordinators must support URL-based deep linking
nav-modal-sheets
- Present modals via coordinator, not inline
nav-no-navigationlink
- Never use NavigationLink(destination:) — use navigationDestination(for:)
5. Layer Architecture (HIGH)
layer-dependency-rule
- Domain layer has zero framework imports
layer-usecase-protocol
- Do not add a use-case layer; keep orchestration in ViewModel + repository protocols
layer-repository-protocol
- Repository protocols in Domain, implementations in Data
layer-model-value-types
- Domain models are structs, never classes
layer-no-view-repository
- Views never access repositories directly; ViewModel calls repository protocols
layer-viewmodel-boundary
- ViewModels expose display-ready state only
6. Dependency Injection (MEDIUM-HIGH)
di-environment-injection
- Inject container-managed protocol dependencies via @Environment
di-protocol-abstraction
- All injected dependencies are protocol types
di-container-composition
- Compose
DependencyContainer
in App target and expose VM factories
di-mock-testing
- Every protocol dependency has a mock for testing
7. List & Collection Performance (MEDIUM)
list-constant-viewcount
- ForEach must produce constant view count per element
list-filter-in-model
- Filter/sort in ViewModel, never inside ForEach
list-lazy-stacks
- Use LazyVStack/LazyHStack for unbounded content
list-id-keypath
- Provide explicit id keyPath — never rely on implicit identity
8. Async & Data Flow (MEDIUM)
data-task-modifier
- Use
.task(id:)
as the primary feature data-loading trigger
data-async-init
- Never perform async work in init
data-error-loadable
- Model loading states as enum, not booleans
data-combine-avoid
- Prefer async/await over Combine for new code
data-cancellation
- Use .task automatic cancellation — never manage Tasks manually
How to Use
Read individual reference files for detailed explanations and code examples:
Section definitions
- Category structure and impact levels
Rule template
- Template for adding new rules
Reference Files
File
Description
references/_sections.md
Category definitions and ordering
assets/templates/_template.md
Template for new rules
metadata.json
Version and reference information