swiftpm-modularizationlisted
Install: claude install-skill wei18/apple-dev-skills
# SwiftPM Modularization
## When to invoke
- Starting a new Swift App project and deciding how to split modules.
- Writing the first version of `Package.swift`.
- Wanting to reserve the option of shipping core logic to Android / cross-platform later.
- Introducing CloudKit / GameKit / StoreKit and deciding the import scope.
- User asks "single Package or multiple", "should the App target be thin", "how do I wire DI".
## Default decisions
### Single Package + multiple targets
- **Put all modules in one Swift Package**, splitting by target (named e.g. `<Project>Kit`).
- Don't start with multiple Packages — they only add `Package.swift` maintenance cost and CI resolution time.
### Very thin App target
- The App target only contains:
- `@main`, the `App` struct
- `Info.plist`, entitlements
- Assets / Asset Catalog
- A single DI composition root (wiring protocols to concrete implementations)
- All views, logic, and Storage live in the Package.
- The App target is **not tested** (it can't really be); all testable logic is in the Package.
### Dependencies flow upward, never downward
```
Engine (pure Swift core)
↑
GameState / Domain
↑
Service modules (CloudKit / GameKit / Storage / Telemetry)
↑
UI module (SwiftUI)
↑
App target
```
### Restricted Apple framework imports
- `CloudKit` is imported only in its designated service target.
- Same for `GameKit` / `StoreKit`.
- The UI and logic layers consume these **via injected protocols**, never importing the