name project-structure description Project organization and directory structure. Use when creating features, organizing files, or understanding the codebase layout.
Skill: Project Structure
Guide for project organization and directory structure.
When to use this skill
Create a new feature module
Organize files correctly
Understand the codebase layout
Add extensions to existing types
Project Overview
{AppName}/
โโโ App/
โ โโโ Sources/
โ โ โโโ {AppName}App.swift # Minimal entry point (imports AppKit)
โ โ โโโ Resources/
โ โ โโโ Assets.xcassets/
โ โโโ Tests/
โ โโโ UI/ # UI tests only
โโโ AppKit/ # Testable app code (SPM local package)
โ โโโ Package.swift
โ โโโ Sources/
โ โ โโโ AppContainer.swift # Composition Root (centralized DI)
โ โ โโโ Data/
โ โ โ โโโ AppEnvironment+API.swift
โ โ โโโ Presentation/
โ โ โโโ Navigation/
โ โ โ โโโ AppNavigationRedirect.swift
โ โ โโโ Views/
โ โ โโโ RootContainerView.swift
โ โโโ Tests/
โ โโโ Unit/ # Unit tests
โ โโโ Snapshots/ # Snapshot tests
โ โโโ Shared/ # Shared resources
โโโ Features/ # Each feature is an SPM local package
โ โโโ {Feature}/
โ โ โโโ Package.swift
โ โ โโโ ...
โ โโโ Home/
โ โโโ Package.swift
โ โโโ ...
โโโ Libraries/ # Each library is an SPM local package
โ โโโ Core/
โ โ โโโ Package.swift
โ โ โโโ ...
โ โโโ Networking/
โ โโโ DesignSystem/
โ โโโ SnapshotTestKit/
โโโ Shared/
โ โโโ Resources/
โ โโโ Package.swift
โ โโโ ...
โโโ Derived/ # Generated by Tuist (gitignored)
โ โโโ InfoPlists/
โโโ Tuist/
โ โโโ ProjectDescriptionHelpers/
โ โโโ Package.swift # External SPM dependencies + target settings
โโโ Project.swift # Root project (app + UI tests + module packages)
โโโ Workspace.swift # Workspace configuration (code coverage)
โโโ {AppName}.xctestplan # Test plan aggregating all module test targets (SPM strategy only)
โโโ Tuist.swift
โโโ CLAUDE.md
Key Architecture:
App : Minimal entry point that imports ChallengeAppKit
AppKit : Framework containing testable app code (AppContainer, RootContainerView, AppNavigationRedirect). Tests run without TEST_HOST.
Feature Naming
Feature directory names must not contain the word "Feature". Use simple, descriptive names:
// RIGHT
Features/User/
Features/Character/
Features/Home/
// WRONG
Features/UserFeature/
Features/CharacterFeature/
Feature Module Structure
Each feature module follows this internal structure:
FeatureName/
โโโ Package.swift # SPM local package definition
โโโ Sources/
โ โโโ {Feature}Feature.swift # Public entry point (navigation + deep links)
โ โโโ {Feature}Container.swift # Dependency composition (factories)
โ โโโ Domain/
โ โ โโโ Models/
โ โ โ โโโ {Name}.swift # Domain models
โ โ โโโ UseCases/
โ โ โ โโโ Get{Name}UseCase.swift # Business logic
โ โ โโโ Repositories/
โ โ โโโ {Name}RepositoryContract.swift # Repository contracts
โ โโโ Data/
โ โ โโโ DataSources/
โ โ โ โโโ Remote/
โ โ โ โ โโโ {Name}RemoteDataSourceContract.swift
โ โ โ โ โโโ {Name}RESTDataSource.swift
โ โ โ โโโ Local/
โ โ โ โโโ {Name}LocalDataSourceContract.swift
โ โ โ โโโ {Name}MemoryDataSource.swift
โ โ โโโ DTOs/
โ โ โ โโโ {Name}DTO.swift
โ โ โโโ Mappers/
โ โ โ โโโ {Name}Mapper.swift
โ โ โโโ Repositories/
โ โ โโโ {Name}Repository.swift
โ โโโ Presentation/
โ โโโ Navigation/ # Feature-level navigation (inside Presentation)
โ โ โโโ {Feature}IncomingNavigation.swift # Navigation destinations
โ โ โโโ {Feature}OutgoingNavigation.swift # Cross-feature navigation (optional)
โ โ โโโ {Feature}DeepLinkHandler.swift # Deep link handler
โ โโโ {Name}List/
โ โ โโโ Navigator/
โ โ โ โโโ {Name}ListNavigatorContract.swift
โ โ โ โโโ {Name}ListNavigator.swift
โ โ โโโ Tracker/
โ โ โ โโโ {Name}ListTrackerContract.swift
โ โ โ โโโ {Name}ListTracker.swift
โ โ โ โโโ {Name}ListEvent.swift
โ โ โโโ Views/
โ โ โ โโโ {Name}ListView.swift
โ โ โโโ ViewModels/
โ โ โโโ {Name}ListViewModel.swift
โ โ โโโ {Name}ListViewState.swift
โ โโโ {Name}Detail/
โ โโโ Navigator/
โ โ โโโ {Name}DetailNavigatorContract.swift
โ โ โโโ {Name}DetailNavigator.swift
โ โโโ Tracker/
โ โ โโโ {Name}DetailTrackerContract.swift
โ โ โโโ {Name}DetailTracker.swift
โ โ โโโ {Name}DetailEvent.swift
โ โโโ Views/
โ โ โโโ {Name}DetailView.swift
โ โโโ ViewModels/
โ โโโ {Name}DetailViewModel.swift
โ โโโ {Name}DetailViewState.swift
โโโ Tests/
โ โโโ Unit/ # Unit tests (Swift Testing)
โ โ โโโ Domain/
โ โ โ โโโ UseCases/
โ โ โ โโโ Get{Name}UseCaseTests.swift
โ โ โโโ Data/
โ โ โ โโโ Repositories/
โ โ โ โ โโโ {Name}RepositoryTests.swift
โ โ โโโ Presentation/
โ โ โ โโโ Navigation/
โ โ โ โ โโโ {Feature}DeepLinkHandlerTests.swift
โ โ โ โโโ {Name}List/
โ โ โ โโโ ViewModels/
โ โ โ โโโ {Name}ListViewModelTests.swift
โ โ โโโ Feature/
โ โ โโโ {Feature}FeatureTests.swift
โ โโโ Snapshots/ # Snapshot tests (ChallengeSnapshotTestKit)
โ โ โโโ Presentation/
โ โ โโโ {Name}List/
โ โ โโโ {Name}ListViewSnapshotTests.swift
โ โ โโโ __Snapshots__/
โ โโโ Shared/ # Shared resources
โ โโโ Stubs/
โ โ โโโ {Name}+Stub.swift
โ โโโ Mocks/
โ โ โโโ Get{Name}UseCaseMock.swift
โ โ โโโ {Name}RepositoryMock.swift
โ โโโ Fixtures/
โ โ โโโ {name}.json
โ โโโ Extensions/
โ โ โโโ {Name}ViewState+Equatable.swift
โ โโโ Resources/
โ โโโ test-avatar.jpg
โโโ Mocks/ # Public mocks (if needed)
โโโ {Name}RepositoryMock.swift
Presentation Layer Organization
The Presentation layer groups related Views and ViewModels by feature name:
Presentation/
โโโ CharacterDetail/ # Feature: Character detail screen
โ โโโ Navigator/
โ โ โโโ CharacterDetailNavigatorContract.swift
โ โ โโโ CharacterDetailNavigator.swift
โ โโโ Tracker/
โ โ โโโ CharacterDetailTrackerContract.swift
โ โ โโโ CharacterDetailTracker.swift
โ โ โโโ CharacterDetailEvent.swift
โ โโโ Views/
โ โ โโโ CharacterDetailView.swift
โ โโโ ViewModels/
โ โโโ CharacterDetailViewModel.swift
โ โโโ CharacterDetailViewState.swift
โโโ CharacterList/ # Feature: Character list screen
โ โโโ Navigator/
โ โ โโโ CharacterListNavigatorContract.swift
โ โ โโโ CharacterListNavigator.swift
โ โโโ Tracker/
โ โ โโโ CharacterListTrackerContract.swift
โ โ โโโ CharacterListTracker.swift
โ โ โโโ CharacterListEvent.swift
โ โโโ Views/
โ โ โโโ CharacterListView.swift
โ โโโ ViewModels/
โ โโโ CharacterListViewModel.swift
โ โโโ CharacterListViewState.swift
โโโ ...
Naming conventions:
Folder name matches the feature (e.g., CharacterDetail)
Navigator: {Feature}Navigator.swift and {Feature}NavigatorContract.swift
Tracker: {Feature}Tracker.swift, {Feature}TrackerContract.swift, and {Feature}Event.swift
View: {Feature}View.swift
ViewModel: {Feature}ViewModel.swift
ViewState: {Feature}ViewState.swift
Extensions
Extensions of external framework types (Foundation, UIKit, SwiftUI, etc.) must be placed in an Extensions/ folder.
Location
Sources/
โโโ Extensions/
โ โโโ URL+QueryItems.swift
โ โโโ Date+Formatting.swift
โ โโโ String+Validation.swift
โโโ ...
Tests/
โโโ Extensions/
โ โโโ URLSession+Mock.swift
โ โโโ HTTPURLResponse+Mock.swift
โ โโโ URLRequest+BodyData.swift
โโโ ...
Naming Convention
Pattern: TypeName+Purpose.swift
extension URL {
func appendingQueryItems (_ items : [URLQueryItem ]) -> URL { ... }
}
extension URLSession {
static func mockSession () -> URLSession { ... }
}
extension Date {
func formatted (style : DateFormatter .Style ) -> String { ... }
}
Tests Directory Structure
Tests/
โโโ Unit/ # Unit tests (Swift Testing)
โ โโโ Domain/
โ โ โโโ UseCases/
โ โ โโโ Get{Name}UseCaseTests.swift
โ โโโ Data/
โ โ โโโ Repositories/
โ โ โ โโโ {Name}RepositoryTests.swift
โ โ โโโ DataSources/
โ โ โโโ Remote/
โ โ โ โโโ {Name}RemoteDataSourceTests.swift
โ โ โโโ Local/
โ โ โโโ {Name}MemoryDataSourceTests.swift
โ โโโ Presentation/
โ โ โโโ {ScreenName}/
โ โ โโโ ViewModels/
โ โ โโโ {ScreenName}ViewModelTests.swift
โ โโโ Feature/
โ โโโ {Feature}FeatureTests.swift
โโโ Snapshots/ # Snapshot tests (ChallengeSnapshotTestKit)
โ โโโ Presentation/
โ โโโ {ScreenName}/
โ โโโ {ScreenName}ViewSnapshotTests.swift
โ โโโ __Snapshots__/
โโโ UI/ # UI tests (XCTest, App only)
โโโ Shared/ # Shared resources (used by Unit, Snapshots, and UI)
โโโ Stubs/ # Domain model test data
โ โโโ Character+Stub.swift
โ โโโ Location+Stub.swift
โโโ Mocks/ # Internal test mocks
โ โโโ Get{Name}UseCaseMock.swift
โ โโโ {Name}RepositoryMock.swift
โโโ Fixtures/ # JSON fixtures for DTOs
โ โโโ character.json
โ โโโ character_list.json
โโโ Extensions/ # Test helpers (Equatable, etc.)
โ โโโ {Name}ViewState+Equatable.swift
โโโ Scenarios/ # Reusable SwiftMockServer configurations (UI tests)
โ โโโ UITestCase+Scenarios.swift
โโโ Resources/ # Test images
โโโ test-avatar.jpg
Mocks Location
Location Visibility Usage Mocks/ (framework)Public Mocks used by other modules Tests/Shared/Mocks/Internal Mocks shared between Unit and Snapshot tests
FeatureName/
โโโ Mocks/ # Public mocks ({AppName}FeatureNameMocks framework)
โ โโโ {Name}RepositoryMock.swift
โโโ Tests/
โโโ Shared/
โโโ Mocks/ # Internal test-only mocks
โโโ {Name}DataSourceMock.swift
Core Module
Libraries/Core/
โโโ Sources/
โ โโโ AppEnvironment/
โ โ โโโ AppEnvironment.swift # Base environment enum
โ โโโ Feature/
โ โ โโโ FeatureContract.swift # Feature protocol
โ โโโ Navigation/
โ โ โโโ NavigationCoordinator.swift # @Observable path manager
โ โ โโโ NavigatorContract.swift # Navigation protocol
โ โ โโโ NavigationRedirectContract.swift
โ โ โโโ Navigation.swift # Base navigation protocol
โ โ โโโ AnyNavigation.swift # Type-erased wrapper
โ โ โโโ DeepLinkHandler.swift
โ โโโ ImageLoader/
โ โ โโโ ImageLoaderContract.swift
โ โ โโโ CachedImageLoader.swift
โ โ โโโ ImageLoaderEnvironment.swift
โ โ โโโ DiskCache/
โ โ โ โโโ ImageDiskCacheContract.swift
โ โ โ โโโ ImageDiskCache.swift
โ โ โ โโโ DiskCacheConfiguration.swift
โ โ โ โโโ FileSystemContract.swift
โ โ โ โโโ FileSystem.swift
โ โ โโโ MemoryCache/
โ โ โโโ ImageMemoryCacheContract.swift
โ โ โโโ ImageMemoryCache.swift
โ โโโ Tracking/
โ โ โโโ TrackerContract.swift
โ โ โโโ Tracker.swift
โ โ โโโ TrackingEventContract.swift
โ โ โโโ Providers/
โ โ โโโ TrackingProviderContract.swift
โ โ โโโ ConsoleTrackingProvider.swift
โ โโโ Extensions/
โ โโโ ...
โโโ Tests/
โ โโโ Unit/
โ โโโ AppEnvironment/
โ โ โโโ AppEnvironmentTests.swift
โ โโโ Navigation/
โ โ โโโ NavigationCoordinatorTests.swift
โ โโโ Tracking/
โ โโโ TrackerTests.swift
โ โโโ ConsoleTrackingProviderTests.swift
โโโ Mocks/
โโโ NavigatorMock.swift
โโโ TrackerMock.swift
โโโ ImageLoaderMock.swift
โโโ Bundle+JSON.swift
Networking Module
Libraries/Networking/
โโโ Sources/
โ โโโ HTTP/
โ โ โโโ HTTPClient.swift
โ โ โโโ HTTPClientContract.swift
โ โ โโโ Endpoint.swift
โ โ โโโ HTTPMethod.swift
โ โ โโโ HTTPError.swift
โโโ Tests/
โ โโโ Unit/
โโโ Mocks/
โโโ HTTPClientMock.swift
Shared Directory
The Shared/ directory contains app-specific modules (not reusable across apps).
Resources Module
Shared/Resources/
โโโ Package.swift
โโโ Sources/
โ โโโ Extensions/
โ โ โโโ String+Localized.swift # localized() extension
โ โโโ Resources/
โ โโโ Localizable.xcstrings
โโโ Tests/
The Resources module provides:
Localization : Centralized Localizable.xcstrings and String.localized() extension
Bundle.module : Auto-generated by SPM for targets with resources
Derived Directory
Tuist generates files in Derived/ (gitignored):
Derived/
โโโ InfoPlists/
โโโ {AppName}-Info.plist
โโโ {AppName}UITests-Info.plist
Contents: Only Info.plist files for the app and UI tests targets. Module Info.plists are managed by SPM.
No generated Swift code: disableBundleAccessors and disableSynthesizedResourceAccessors are enabled in Project.swift.
App and AppKit Directories
The app code is split into two modules:
App : Minimal entry point with UI tests only
AppKit : Testable app code (unit and snapshot tests run here without TEST_HOST)
App/
โโโ Sources/
โ โโโ {AppName}App.swift # Minimal entry point (imports AppKit)
โ โโโ Resources/
โ โโโ Assets.xcassets/
โ โโโ AppIcon.appiconset/ # Production icon
โ โโโ AppIconDev.appiconset/ # Development icon
โ โโโ AppIconStaging.appiconset/ # Staging icon
โโโ Tests/
โโโ Shared/
โ โโโ Robots/ # Robot pattern for UI interactions
โ โโโ Scenarios/ # Reusable SwiftMockServer configurations
โ โโโ Stubs/ # Test data helpers
โ โโโ Fixtures/ # JSON fixtures
โ โโโ Resources/ # Test images
โโโ UI/ # UI tests only (XCTest)
AppKit/
โโโ Sources/
โ โโโ AppContainer.swift # Composition Root (centralized DI)
โ โโโ Data/
โ โ โโโ AppEnvironment+API.swift # API configuration extension
โ โโโ Presentation/
โ โโโ Navigation/
โ โ โโโ AppNavigationRedirect.swift
โ โโโ Views/
โ โโโ RootContainerView.swift # Root view with navigation
โโโ Tests/
โโโ Unit/ # Unit tests (Swift Testing)
โ โโโ Data/
โ โ โโโ AppEnvironment+APITests.swift
โ โโโ Presentation/
โ โโโ Navigation/
โ โโโ AppContainerNavigationTests.swift
โ โโโ AppNavigationRedirectTests.swift
โโโ Snapshots/ # Snapshot tests
โ โโโ Presentation/
โโโ Shared/ # Shared resources
โโโ Stubs/
Why AppKit? Unit and snapshot tests for app-level code can run without launching the app (no TEST_HOST required).
File Naming Summary
Component Naming Pattern Example Feature folder {Name}/Character/Public entry {Feature}Feature.swiftCharacterFeature.swiftContainer {Feature}Container.swiftCharacterContainer.swiftNavigation Presentation/Navigation/{Feature}IncomingNavigation.swiftPresentation/Navigation/CharacterIncomingNavigation.swiftDomain model {Name}.swiftCharacter.swiftDTO {Name}DTO.swiftCharacterDTO.swiftUseCase {Action}{Name}UseCase.swiftGetCharacterUseCase.swiftRepository {Name}Repository.swiftCharacterRepository.swiftMapper {Name}Mapper.swiftCharacterMapper.swiftContract {Name}Contract.swiftCharacterRepositoryContract.swiftDataSource Contract {Name}{Type}DataSourceContract.swiftCharacterRemoteDataSourceContract.swiftDataSource Implementation {Name}{Impl}DataSource.swiftCharacterRESTDataSource.swift, CharacterMemoryDataSource.swiftNavigator {ScreenName}Navigator.swiftCharacterDetailNavigator.swiftNavigatorContract {ScreenName}NavigatorContract.swiftCharacterDetailNavigatorContract.swiftTracker {ScreenName}Tracker.swift
Checklist
App contains only {AppName}App.swift and UI tests (with Robots, Scenarios, Stubs, Fixtures)
AppKit contains testable code: AppContainer.swift, RootContainerView.swift, AppNavigationRedirect.swift
Feature folder does not contain "Feature" suffix
{Feature}Container.swift for dependency composition
{Feature}Feature.swift as public entry point with makeMainView() and resolve()
Sources organized by layer: Domain, Data, Presentation
Navigation folder inside Presentation/Navigation/
Presentation organized by screen: {ScreenName}/Navigator/, {ScreenName}/Tracker/, {ScreenName}/Views/, {ScreenName}/ViewModels/
Unit tests in Tests/Unit/ mirroring Sources structure
Snapshot tests in Tests/Snapshots/
Feature tests in Tests/Unit/Feature/
Extensions in dedicated Extensions/ folder
Extension files named {Type}+{Purpose}.swift
Public mocks in Mocks/, internal mocks in Tests/Shared/Mocks/
Stubs in Tests/Shared/Stubs/
JSON fixtures in Tests/Shared/Fixtures/
Test resources in Tests/Shared/Resources/
Module has its own Package.swift with source, mocks, and test targets