Swift architecture
When to activate: iOS/macOS app architecture, MVVM, TCA, Clean Architecture, dependency injection, modular design in Swift appsFrom its SKILL.md
npx -y skills add Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack --skill swift-architectureAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 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.
SKILL.md
5.2 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it
Swift App Architecture Patterns
MVVM with SwiftUI
// Model — pure data, no UI dependencies
struct Article: Identifiable, Codable {
let id: UUID
let title: String
let body: String
let publishedAt: Date
}
// ViewModel — transforms model for display, owns async operations
@MainActor
final class ArticleListViewModel: ObservableObject {
@Published private(set) var articles: [Article] = []
@Published private(set) var isLoading = false
@Published var errorMessage: String?
private let repository: any ArticleRepository
init(repository: any ArticleRepository) {
self.repository = repository
}
func load() async {
isLoading = true
defer { isLoading = false }
do {
articles = try await repository.fetchAll()
} catch {
errorMessage = error.localizedDescription
}
}
}
// View — purely declarative, no business logic
struct ArticleListView: View {
@StateObject private var vm: ArticleListViewModel
init(repository: any ArticleRepository) {
_vm = StateObject(wrappedValue: ArticleListViewModel(repository: repository))
}
var body: some View {
Group {
if vm.isLoading { ProgressView() }
else { List(vm.articles) { ArticleRow(article: $0) } }
}
.task { await vm.load() }
.alert("Error", isPresented: .constant(vm.errorMessage != nil)) { }
message: { Text(vm.errorMessage ?? "") }
}
}
Repository Pattern
protocol ArticleRepository {
func fetchAll() async throws -> [Article]
func fetch(id: UUID) async throws -> Article?
func save(_ article: Article) async throws
}
struct RemoteArticleRepository: ArticleRepository {
let client: APIClient
func fetchAll() async throws -> [Article] {
try await client.get("/articles", as: [Article].self)
}
func fetch(id: UUID) async throws -> Article? {
try await client.get("/articles/\(id)", as: Article.self)
}
func save(_ article: Article) async throws {
try await client.post("/articles", body: article) as Article
}
}
// In-memory implementation for tests/previews
final class InMemoryArticleRepository: ArticleRepository {
var articles: [Article] = []
func fetchAll() async throws -> [Article] { articles }
func fetch(id: UUID) async throws -> Article? { articles.first { $0.id == id } }
func save(_ article: Article) async throws { articles.append(article) }
}
Dependency Injection Container
// Using point-free/swift-dependencies style
import Dependencies
extension DependencyValues {
var articleRepository: any ArticleRepository {
get { self[ArticleRepositoryKey.self] }
set { self[ArticleRepositoryKey.self] = newValue }
}
}
private enum ArticleRepositoryKey: DependencyKey {
static let liveValue: any ArticleRepository = RemoteArticleRepository(client: .live)
static let testValue: any ArticleRepository = InMemoryArticleRepository()
static let previewValue: any ArticleRepository = InMemoryArticleRepository(articles: .preview)
}
// Usage in ViewModel
@MainActor
final class ArticleListViewModel: ObservableObject {
@Dependency(\.articleRepository) var repository
}
Clean Architecture Layers
Presentation (SwiftUI views + ViewModels)
↓
Domain (Use Cases / Interactors)
↓
Data (Repositories → Remote + Local)
// Domain layer — use case
struct FetchArticlesUseCase {
let remote: any ArticleRepository
let local: any ArticleRepository
func execute() async throws -> [Article] {
do {
let articles = try await remote.fetchAll()
for article in articles { try await local.save(article) }
return articles
} catch {
// Fallback to local cache
return try await local.fetchAll()
}
}
}
Modular Feature Design
// Each feature is a standalone SPM module
// Feature/ArticleFeature/Sources/ArticleListView.swift
public struct ArticleListView: View {
public init(store: ArticleStore) { self.store = store }
private let store: ArticleStore
// ...
}
// App target wires features together
import ArticleFeature
import ProfileFeature
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
TabView {
ArticleListView(store: .live)
ProfileView(store: .live)
}
}
}
}
Common Anti-Patterns
- Fat ViewControllers / fat Views — move business logic to ViewModel or UseCase
- Views depending on networking — always go through ViewModel → Repository
- Singleton abuse — use DI instead; singletons make testing hard
- Circular module dependencies — extract shared types to a
Coremodule - Tight coupling between features — communicate via protocols or shared events, not direct imports
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.
Gives 0 of the 12 instructions most architecture codebase skills give in ~1.1k tokens
Counted across 811 of the 1,134 authors here whose files we hold, read 2026-08-07
- Ask the user which candidate to explorein 45 of 811, across 15 files
- Apply the deletion test to suspected shallow modulesin 43 of 811, across 15 files
- Read any relevant architecture decision records firstin 31 of 811, across 8 files
- Use exact glossary terms in every suggestionin 30 of 811, across 10 files
- Accept dependencies instead of creating themin 24 of 811, across 5 files
- Include before and after visualisations for each candidatein 24 of 811, across 5 files
- Read the domain glossary before exploringin 24 of 811, across 6 files
- Return results instead of producing side effectsin 23 of 811, across 4 files
- Explore the codebase for shallow modules and frictionin 23 of 811, across 3 files
- Introduce seams only where things varyin 22 of 811, across 3 files
- Reduce the number of methodsin 21 of 811, across 2 files
- Design deep modules with small interfacesin 21 of 811, across 3 files
Said here and by no other author read
- move business logic to viewmodel or usecase
- access data through viewmodel and repository
- extract shared types to core module
- decouple features via protocols or shared events
- make features standalone swift package modules
- define repositories as protocols
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.