Building SwiftUI Navigation for a Modular App
Introduction In my previous post, I surveyed three approaches to SwiftUI navigation at scale: shared routers, navigation frameworks, and per-module coordinators. I explained the trade-offs of each. This post is the implementation. A demo project with five feature modules, a tab bar, a modal settings flow, an onboarding gate, deep linking, and unit tests. The architecture: Vertical feature modules that can’t see each other A generic Router per module that holds navigation state Each module composes its own views internally A single AppCoordinator for cross-module orchestration No coordinator per feature module The Module Structure App (composition root) ├── Home (tab — list → detail push) ├── Profile (tab — static screen, edit sheet) ├── Account (tab — logout action) ├── Onboarding (separate flow — experiment-based branching) ├── UserSettings (modal sheet) └── Navigation (shared — Router generic) Each feature package depends on Navigation but never on each other. The Navigation package contains only the generic Router. Pure infrastructure with no app-specific types. The App target is the only thing that imports everything. ...