Provides the 4-layer Swift app architecture (Apps, Features, Services, SDKs) including layer responsibilities, dependency rules, placement guidance, feature creation, configuration, code style, and reference examples. Use when the user asks about the architecture, needs to understand layers, wants to add code, create features, or review architectural compliance.
How this skill is triggered — by the user, by Claude, or both
Slash command
/swift-app-architecture:swift-architectureThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
A layered architecture for building Swift applications — macOS apps, CLI tools, and servers — emphasizing separation of concerns, code reuse across entry points, and testability through use case protocols.
A layered architecture for building Swift applications — macOS apps, CLI tools, and servers — emphasizing separation of concerns, code reuse across entry points, and testability through use case protocols.
| Situation | Document |
|---|---|
| Understanding the architecture overview | Start here |
| Understanding why the architecture works this way | principles.md |
| Deciding which layer code belongs in | layers.md |
| Creating a new feature module | creating-features.md |
| Setting up configuration or data paths | configuration.md |
| Writing or reviewing code style | code-style.md |
| Seeing a full end-to-end implementation | examples.md |
┌─────────────────────────────────────────────────────────────┐
│ Apps Layer │
│ ┌──────────────────┐ ┌──────────────────┐ ┌────────────┐ │
│ │ MyMacApp │ │ MyCLIApp │ │ MyServer │ │
│ │ (@Observable │ │ (ArgumentParser │ │ App │ │
│ │ models + views) │ │ commands) │ │ │ │
│ └──────────────────┘ └──────────────────┘ └────────────┘ │
│ Entry points, I/O, platform-specific concerns │
└────────────────────────┬────────────────────────────────────┘
│ uses
▼
┌─────────────────────────────────────────────────────────────┐
│ Features Layer │
│ ┌──────────────────┐ ┌──────────────────┐ ┌────────────┐ │
│ │ ImportFeature │ │ ExportFeature │ │ Sync │ │
│ │ (UseCases) │ │ (UseCases) │ │ Feature │ │
│ └──────────────────┘ └──────────────────┘ └────────────┘ │
│ Multi-step orchestration via UseCase / StreamingUseCase │
└────────────────────────┬────────────────────────────────────┘
│ uses
▼
┌─────────────────────────────────────────────────────────────┐
│ Services Layer │
│ ┌───────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ CoreService │ │ AuthService │ │ StorageService │ │
│ │ • Models │ │ • Config │ │ • Persistence │ │
│ │ • Shared │ │ • Tokens │ │ • File paths │ │
│ │ types │ │ │ │ │ │
│ └───────────────┘ └──────────────┘ └──────────────────┘ │
│ Models, configuration, shared stateful utilities │
└────────────────────────┬────────────────────────────────────┘
│ uses
▼
┌─────────────────────────────────────────────────────────────┐
│ SDKs Layer │
│ ┌───────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ API Clients │ │ CLI Wrappers │ │ Utility SDKs │ │
│ │ (REST, etc.) │ │ (git, etc.) │ │ (parsing, etc.) │ │
│ └───────────────┘ └──────────────┘ └──────────────────┘ │
│ Stateless Sendable structs — reusable across projects │
└─────────────────────────────────────────────────────────────┘
Platform-specific entry points that handle I/O and own @Observable state.
@Observable models live here — not in Services or Features@Observable models (not multiple independent properties)Multi-step orchestration via use case protocols.
UseCase or StreamingUseCase protocolsAsyncThrowingStream for progress reporting@Observable — that belongs in the Apps layerShared models, configuration, and stateful utilities used across features.
Low-level, reusable building blocks with no app-specific logic.
Sendable structs, not actors or classesThe four layers are a logical structure. How they map to the build system varies:
Package.swift, grouped by layer folders. Good default for most projects.Package.swift. Common in large or multi-team codebases.Always match the convention already established in the codebase. If starting fresh and unsure, ask which approach to use.
Dependencies flow downward only:
Apps → Features → Services → SDKs
UseCase / StreamingUseCase conformers for multi-step operationsSendable structs, no business conceptsFor the reasoning behind these principles, see principles.md.
useCase.stream() → print progress
useCase.run() → print result
useCase.stream() → @Observable model → View
Both CLI commands and Mac models share the same use cases. The difference:
@Observable models to update observable state| What you're adding | Where it goes | Layer |
|---|---|---|
| SwiftUI views | apps/MyMacApp/Views/ | Apps |
@Observable models | apps/MyMacApp/Models/ | Apps |
| CLI commands | apps/MyCLIApp/ | Apps |
| Server handlers | apps/MyServerApp/ | Apps |
| Multi-step orchestration | features/MyFeature/usecases/ | Features |
| Feature-specific types | features/MyFeature/services/ | Features |
| Shared data models | services/CoreService/Models/ | Services |
| Configuration / settings | services/AuthService/, services/StorageService/ | Services |
| Stateful shared utility | services/MyService/ | Services |
| Single API call wrapper | sdks/APIClientSDK/ | SDKs |
| Single CLI command wrapper | sdks/CLISDK/, sdks/GitSDK/ | SDKs |
| Use case protocol definitions | sdks/Uniflow/ | SDKs |
For decision flowcharts and boundary guidance, see layers.md.
Before adding code:
@Observable only in the Apps layer?Before creating a new module:
<Name><Layer> naming convention?LazyVStack / LazyHStack for efficient scrollingAsyncThrowingStreamI'm adding a new feature to the app. Where does it go? Create three things:
features/MyFeature/ — use cases that orchestrate the logicapps/MyMacApp/Models/ — @Observable model consuming use case streamsapps/MyCLIApp/ — command consuming use cases directly (if CLI access needed)Where do @Observable models go?
Always in the Apps layer (apps/MyMacApp/Models/). Never in Features or Services.
Can a feature depend on another feature? No. If two features need shared logic, extract to a Service or SDK. Compose at the App layer.
How do I share code between CLI and Mac app? Put all shared logic in Features (use cases). Both CLI commands and Mac models consume the same use cases.
Documentation follows this directory structure:
docs/
├── proposed/ # In-progress specs and proposals
└── completed/ # Finished implementation docs
docs/proposed/ when planning new workdocs/completed/ once implementation is mergedplugin/skills/ is the single source of truth for architecture documentationnpx claudepluginhub gestrich/swift-app-architecture --plugin swift-app-architectureSelects and applies Swift architecture playbooks (MVVM, TCA, Clean Architecture, VIPER, etc.) for SwiftUI/UIKit codebases. Guides new features, refactors, and migrations with fit checks and incremental plans.
Helps select, implement, or migrate between Apple platform architecture patterns (MV, MVVM, MVI, TCA, Clean Architecture, VIPER, Coordinator) for SwiftUI and UIKit apps, including a decision framework and review checklist.
Provides expert guidance for iOS/macOS development with Swift, SwiftUI, UIKit, Core Data, Combine, Xcode projects, app architectures, build errors, and performance optimization.