Tuist-based modular iOS template for feature-oriented apps with explicit boundaries between layers.
This repository gives you a clean starting point for a modular iOS app. Each module has a clear purpose and depends on other modules only through explicit Tuist wiring.
The root application lives in Projects/App.
- Tuist version:
4.203.1 - Root manifest:
Tuist.swift - Workspace manifest:
Workspace.swift - Local plugins:
The root manifest enables enforceExplicitDependencies, so module relationships stay visible instead of being implied.
The repo is organized around these layers:
Feature- User-facing flows and screens.
Domain- Business rules and domain logic.
Core- Shared capability modules such as networking, storage, or services.
Common- Shared UI modules, design system pieces, and reusable visual components.
NetworkService- Networking layer modules for API clients, request infrastructure, and service wrappers.
Shared- Cross-cutting utilities such as helpers, extensions, and logging.
Navigations- Shared navigation flow modules and route coordination.
MainAssembly- Top-level app composition modules that wire the root feature set together.
The current template also includes an App project as the root application entry point.
Module scaffolding lives in Tuist/Templates.
Scripts/GenerateModule.swift uses those templates to create modules. The duplicate template plugin was removed so the template source stays in one place.
- macOS
- Xcode
mise- Tuist installed through
mise
Set project metadata.
- Run
make init - Enter the project name, organization name, minimum deployment target, and UI framework when prompted.
- If
Projectsis still empty, this also bootstraps a minimalAppproject sotuist generatehas a project to load. - Choose
SwiftUIwhen you want a SwiftUI starter app. This requires a minimum deployment target of iOS 14.0 or newer. - Choose
UIKitwhen you want the UIKit starter app. - You can enter
16or16.0; the initializer normalizes it to16.0before writing the environment file.
- Run
Set signing information.
- Run
make signing - Enter your Apple Developer Team ID when prompted.
- Run
Generate the Xcode project and workspace.
- Run
make generate
- Run
make init- Runs
swift Scripts/InitEnvironment.swift - Writes project metadata, minimum deployment target, and UI framework into
Plugin/EnvironmentPlugin/ProjectDescriptionHelpers/ProjectEnvironment.swift - Bootstraps a starter app in
Projects/Appwhen no project manifests exist yet
- Runs
make signing- Runs
swift Scripts/CodeSigning.swift - Writes signing settings into
Tuist/ProjectDescriptionHelpers/SettingsDictionary/CodeSign.swift
- Runs
make generate- Runs
tuist install - Runs
tuist generate
- Runs
make ci_generate- Runs
tuist install - Runs
TUIST_ENV=CI tuist generate
- Runs
make cd_generate- Runs
tuist install - Runs
TUIST_ENV=CD tuist generate
- Runs
make module- Runs
swift Scripts/GenerateModule.swift - Creates a new module under
Projects/<Layer>/<ModuleName> - If the module already exists, the generator asks whether you want to overwrite it or skip it
- Runs
make dependency- Runs
swift Scripts/NewDependency.swift - Adds a new Swift Package dependency and its helper entry
- Runs
make clean- Deletes generated
.xcodeprojand.xcworkspacefiles
- Deletes generated
make reset- Runs
tuist clean - Deletes generated
.xcodeprojand.xcworkspacefiles
- Runs
make module asks for:
- Layer
- Module name
- Whether the module needs:
- Interface target
- Testing target
- Unit test target
- UI test target
Generated targets are wired through shared helpers in Tuist/ProjectDescriptionHelpers and dependency helpers in Plugin/DependencyPlugin.
- Run
make module. - Enter a layer name:
FeatureDomainCoreSharedCommonNetworkServiceNavigationsMainAssembly
- Enter the module name.
- Answer the target prompts.
InterfaceTestingUnitTestsUITests
- Review the generated files.
The generator will:
- Create
Projects/<Layer>/<ModuleName>/Project.swift - Register the module in
Plugin/DependencyPlugin/ProjectDescriptionHelpers/ModulePaths.swift - Create
XCConfig/<ModuleName>/DEV.xcconfig - Create
XCConfig/<ModuleName>/STAGE.xcconfig - Create
XCConfig/<ModuleName>/PROD.xcconfig - Scaffold the selected targets from
Tuist/Templates
If a module with the same name already exists, you will see a prompt:
n- Skip generation and keep the current files.
y- Remove the existing module scaffold and generate it again.
If you need a new Swift Package dependency, run make dependency after the package is added to Package.swift.
Example: create a feature module named AuthFeature.
- Run
make module. - Enter
Featureas the layer. - Enter
AuthFeatureas the module name. - Choose the targets you need.
- For a standard feature module, the usual choices are:
InterfaceTestingUnitTestsUITests
- For a standard feature module, the usual choices are:
After generation, you should see:
Projects/Feature/AuthFeature/Project.swiftProjects/Feature/AuthFeaturesource and test scaffolding fromTuist/TemplatesXCConfig/AuthFeature/DEV.xcconfigXCConfig/AuthFeature/STAGE.xcconfigXCConfig/AuthFeature/PROD.xcconfig- A new entry in
Plugin/DependencyPlugin/ProjectDescriptionHelpers/ModulePaths.swift
If the module needs Swift Package dependencies, add them first, then run make dependency so the helper entry stays in sync.
Modules live under:
Projects/<Layer>/<ModuleName>Example modules:
Projects/App
Projects/Feature/AuthFeature
Projects/Domain/AuthDomain
Projects/Core/Networking
Projects/Common/DesignSystem
Projects/NetworkService/NetworkService
Projects/Navigations/AppNavigation
Projects/MainAssembly/AppAssembly
Projects/Shared/LoggingTypical folder roles:
Projects/App- Root application target and app-specific resources.
Projects/Feature- User-facing screens and flows.
Projects/Domain- Business rules and domain entities.
Projects/Core- Shared capability modules such as networking or storage infrastructure.
Projects/Common- Shared UI components and design system pieces.
Projects/NetworkService- API clients and service wrappers.
Projects/Navigations- Shared navigation flow modules and route coordination.
Projects/MainAssembly- Root composition modules that assemble screens, flows, and dependencies.
Projects/Shared- Utilities, helpers, extensions, and logging.
- Default environment is
DEV TUIST_ENV=CIdisables dev-only scripts such as SwiftLintTUIST_ENV=CDalso disables dev-only scriptsmake initnow asks for the minimum deployment target and the UI framework before generating the starter app scaffold
tuist inspect dependencies --only implicitshould stay clean.Scripts/SwiftLintRunScript.shis used by dev builds when SwiftLint is available.- The repository defaults to iOS 16.0 in the environment helper, but
make initcan now regenerate it with a different minimum deployment target. make generateexpects valid project manifests underProjects/**.
Tuist/Templates currently contains:
InterfaceSourcesTestingTestsUITests
These templates are the reference for module bootstrapping.
- If
make generatereports a deployment target version error, runmake initagain and enter a valid version such as16or16.0. - If
make modulesays the module already exists, choose a new module name or answeryto overwrite the existing scaffold. - If
tuist generatefails after a module change, check whetherPlugin/DependencyPlugin/ProjectDescriptionHelpers/ModulePaths.swiftcontains duplicate cases for the same module name.