Clean Architecture in SwiftUI (Part 1): How to Organize Files in a Scalable Project
In this article, I am not going to explain what clean architecture is or what the Domain or Presentation layers are, those basic things you…
Clean Architecture in SwiftUI (Part 1): How to Organize Files in a Scalable Project

In this article, I am not going to explain what clean architecture is or what the Domain or Presentation layers are, those basic things you can already find in different articles. If you want some reference — Clean Architecture blog (Uncle Bob), another medium post by Wahyu Alfandi.
If you already know the basics and want to explore how to structure Clean Architecture properly, so that you do not need major refactoring later for new requirements, this article may help you. Here I am going to mostly talk about which files should go into which layer. Instead, I am going to show you the skeleton of a medium to large scale Application.
Even though we know which things go where, we get confused when it comes to complex projects and modularisation and what is the best practice to keep things organized and after all of it having that satisfaction about your ordering of each item to its right place. I know everyone has their own taste. However, I’m sharing mine here, so you can compare it with yours or directly follow it in your project.
Since we are working with SwiftUI and SwiftUI views work well with an observable view model for better flexibility and state management, we will keep MVVM inside the Presentation Layer. With that, let’s see the initial project structure.
📦 MyApp
├── 📁 App # Application Lifecycle & Composition Root
│ ├── MyApp.swift
│ ├── AppCoordinator.swift # Manages global navigation stacks, tabs, and routes
│ ├── DIContainer.swift # Instantiates & cross-injects UserSessionManager
│ ├── 📁 Environment # Config files for different environment
│ └── 📁 Resources
│ ├── Info.plist
│ ├── Localizable.string # Localize strings for different language and region
│ ├── coredata.xcdatamaodel # Coredata DB file.
│ └── LaunchScreen # Initial Launch Screen Stroybaord
│
├── 📁 Presentation
├── 📁 Domain
├── 📁 Data
├── 📁 Core
├── 📁 Infrastructure
└── 📁 Tests
├── DomainTests
├── DataTests
└── PresentationTests
I hope you get the basic idea here by looking into the above structure. I want to point out some of the important things that we generally miss initially later we struggle to figure out where should put this.
App Layer: If you are usingAppDelegate and SceneDelegate you can keep these files in App folder.
- Resources: keep the app level resource files like
Coredata. xcdatamodelfile,info.plist,LaunchScreen.storyboardto App folder. So that these files can easily accessible and make those unique. Other resources file related to UI will go to Presentation layer.
📁 Presentation
├── 📁 Common
│ ├── 📁 Components
│ ├── 📁 Extensions
│ ├── 📁 Modifiers
│ ├── 📁 Theme
│ │ ├── AppColors.swift
│ │ ├── AppFonts.swift
│ │ └── AppSpacing.swift
│ ├── 📁 Utilities
│ └── 📁 States
│ └── AppUIState.swift # APP UI States like theme, navbar color which are dynamic
│
├── 📁 Resources # All the UI related resource files like images, colors and fonts etc.
│ ├── Assets.xcassets # Color, Images
│ ├── Fonts.ftt
│ ├── 📁 Jsons # Json for preview models or mock data
│ └── 📁 Animations
│
└── 📁 Features
└── 📁 Root
Presentation Layer: Here I want to point out couple of things like —
- Theme: Keep your custom
coloursandfontorlayoutrelated files in the Theme directory of presentation layer rather than scattering them across feature directories or separate model folders. This helps keep the project maintainable and reduces redundancy. - States: At the initial stage, design an
AppUIStatefor your dynamic theme, font, or any global message liketoast message. so that you do not struggle later (There are some other states that view can depend on, I’ll cover those in a later section). - Resources: All UI-related resources can be kept inside this directory, Also any json or pdf files that are used for Preview panel, you can put here also. You will likely find this convenient later.
- Models: I don’t see the need for a separate
Modelscategory inside presentation layer or feature modules. you can keep your model object separate in Domain layer. - Common: This folder is basically for
View Extensions,Modifiers, CustomComponents,UIStatesand UI related objects. Although theCore Layeris generally responsible for common and shared file, then why can’t store there, because these files are completely part of UI, and you create these files so you can reuse them in your UI layer efficiently. So I separate these insidePresentationLayer/Common/Folder.
📁 Domain
├── 📁 Entities
│ ├── User.swift
│ └── 📁 Errors
│ ├── AuthError.swift
│ └── ValidationError.swift
│
├── 📁 Repositories
│ └── AuthRepository.swift
└── 📁 UseCases
Domain Layer: I do not want to discuss more about domain layer, here you mostly define the UseCases and protocols for Repositories and Entities or Models. One thing I want to share my thoughts about the Errors Folder
- Errors: Error Model is something you can define to its respective layer. like
NetworkErrorinCore/Network/andCheckoutErrorinDomain/Entities/Errors/. So that when modularising your project you can easily separate those out.
📁 Core
├── 📁 Constants
│ ├── APIConstants.swift
│ └── AppConstants.swift
│
├── 📁 Extensions
│ ├── String+Extension.swift
│ └── Date+Extension.swift
│
├── 📁 Managers
│ ├── SessionManager.swift
│ ├── AppStateManager.swift
│ └── PermissionManager.swift
│
├── 📁 Services
│ ├── AnalyticService.swift
│ ├── LoggerService.swift
│ ├── Reachability.swift
│ └── DeviceInfo.swift
│
├── 📁 Protocols
│ ├── Coordinatable.swift
│ ├── Routable.swift
│ ├── Cacheable.swift
│ └── Loggable.swift
│
├── 📁 Configuration
│ ├── BuildConfiguration.swift
│ └── FeatureFlagConfiguration.swift
│
└── 📁 Security
├── EncryptionManager.swift
└── BiometricAuthManager.swift
Before moving to Data Layer I want to discuss about the Core and Infrastructure Layer, so that It will help you easily understood.
Core Layer: It is one of the most interesting component of clean architecture. The core layer acts as a mediator to provide access to all low level code, other frameworks / modules. So according to the SOLID principle in the Core Layer you should define interfaces and pure Swift code. Then all the heavy works like framework imports, actual implementation goes to Infrastructure Layer. It basically behaves as a facade to low level modules.
Here You can keep States, Managers, Services apart from that Constants , Extensions (not related to UI). From the above structure you can able to identify what kind of files go here.
📁 Infrastructure
├── 📁 Persistence
│ ├── CoreData
│ │ ├── CoreDataStack.swift
│ │ ├── Entities
│ │ └── Migrations
│ ├── Realm
│ │ └── RealmManager.swift
│ ├── UserDefaults
│ │ └── UserDefaultsManager.swift
│ └── Keychain
│ └── KeychainManager.swift
│
├── 📁 Services
│ ├── Analytics
│ │ └── FirebaseAnalyticsService.swift
│ ├── PushNotification
│ │ └── PushNotificationManager.swift
│ ├── Location
│ │ └── LocationManager.swift
│ ├── Logging
│ │ ├── SentryLogger.swift
│ │ └── DefaultLogger.swift
│ └── Authentication
│ ├── OAuthService.swift
│ └── BiometricService.swift
│
├── 📁 Configuration
│ ├── AppConfig.swift
│ ├── FirebaseRemoteConfig.swift
│ └── BuildSettingsConfig.swift
│
├── 📁 Security
│ ├── EncryptionManager.swift
│ └── CertificatePinning.swift
│
├── 📁 BackgroundTasks
│ ├── BackgroundSyncManager.swift
│ ├── TaskScheduler.swift
│ └── UploadManager.swift
│
└── 📁 Monitoring
├── CrashReporter.swift
└── NetworkLogger.swift
Infrastructure Layer: If you are wondering about Infrastructure layer, you can check the Onion Architecture for a better understanding of this layer in clean architecture. This is the layer which is responsible for handling Core feature implementation, bridging with 3rd party frameworks and low level frameworks. If you want to place it into the clean architecture diagram, it will be at the outmost layer. It wraps those heavy low level features inside it, so that Core Layer remain clean and simpler. Core Layer defines the requirement, Infrastructure layer provides the implementation of those requirements.
If you noticed I have kept out the Network Component(APIClient) from the Infrastructure Layer, based on above statement it should it be part of Infrastructure Layer but I want to keep it in the Data Layer. Why? this is something most debating topic here.
First let’s discuss what the Network Component does, it receives requests, which contain paths, json schema to fetch data from server then parse responses into DTOs, so here network paths and DTOs are completely part of Data Layer, and if you are using URLSession as your network client, which is purely part of swift foundation code. So keeping it inside Data Layer save you writing some complex boilerplate code to just to satisfy the dogmatic design rule. However, If you are working with a 3rd party library for APIClient it is better to keep it inside Infrastructure Layer
📁 Data
├── 📁 Network
│ ├── APIClient.swift
│ ├── Endpoint.swift
│ └── Interceptors
│ ├── AuthInterceptor.swift
│ └── RetryInterceptor.swift
│
├── 📁 DTOs
│ ├── 📁 Request
│ └── 📁 Response
│
├── 📁 Mappers
│ └── OrderMapper.swift
│
├── 📁 RepositoryImpl
│
├── 📁 DataSources
│ ├── 📁 Remote
│ └── 📁 Local
│
└── 📁 SyncEngines
Data Layer: Finally the Data Layer, I think you already know why I kept this section for last, the reason is the networking component. Since I have already discussed about it above, there is nothing much to discuss about it. Here one thing I want to mention when you design app keep in mind about the SyncEngine, so that when you try to provide offline feature it comes handy.
That’s all for this article about how you should structure your app at initial point of time. here is the github link for this project for better understanding. Stay tuned for the 2nd part which have an Example of actual implementation.
메타데이터
- post_id
- 0dbbbd5eba17
- slug
- clean-architecture-in-swiftui-part-1-how-to-organize-files-in-a-scalable-project-0dbbbd5eba17
- url
- https://medium.com/@bhabanishankar777/clean-architecture-in-swiftui-part-1-how-to-organize-files-in-a-scalable-project-0dbbbd5eba17
- canonical_url
- https://medium.com/@bhabanishankar777/clean-architecture-in-swiftui-part-1-how-to-organize-files-in-a-scalable-project-0dbbbd5eba17
- author_url
- https://medium.com/@bhabanishankar777
- status
- ok
- fetched_at
- 2026-06-09 14:34:10