Type-first organization places every view controller, model, and service in application-wide buckets. It looks tidy in a small project but scatters one product feature across distant directories. Feature-first organization keeps code that changes together close: CourseList can contain its view, presentation model, routes, and feature-specific models.
The application layer owns composition, scene setup, top-level routing, and environment selection. Feature folders own user-visible capabilities. Domain or core areas hold genuinely cross-feature policy, while infrastructure contains concrete system adapters. Shared UI should include stable reusable components, not every view used twice.
Folders communicate intent but do not enforce dependency rules. Begin with namespaces, access control, review conventions, and tests. Extract a Swift package or target only when build isolation, ownership, reuse, dependency enforcement, or build performance makes the extra boundary worthwhile.