Tuist Migration
Integrate Tuist into an existing iOS project with SPM local packages, without modifying the modules' Package.swift files. Tuist acts as an orchestration layer that generates the .xcodeproj/.xcworkspace from declarative Swift manifests.
Fundamental Principle
Tuist does not touch modules, it only orchestrates the project that consumes them. The Package.swift files remain intact. If Tuist is removed later, the modules are still functional SPM packages.
Reference Project
Use the current project's Tuist configuration (Tuist/ProjectDescriptionHelpers/, Project.swift, Workspace.swift, Tuist.swift, Tuist/Package.swift) as the primary reference for API syntax and helper patterns. Never copy configurations, bundle IDs, modules, or dependencies — adapt patterns to the target project using audit data.
Migration Phases
8 sequential phases. Each has a script and/or prompt template in the bundled resources.
| # |
Phase |
Script |
Prompt |
Output |
| 1 |
Audit |
scripts/audit.sh |
references/prompts/01-audit.md |
AUDIT_REPORT.md |
| 2 |
Base structure |
— |
references/prompts/02-base-structure.md |
Tuist.swift, Tuist/Package.swift, .gitignore |
| 3 |
Helpers |
— |
references/prompts/03-helpers.md |
Tuist/ProjectDescriptionHelpers/*.swift |
| 4 |
Generation |
scripts/generate.sh |
references/prompts/04-generation.md |
Project.swift, Workspace.swift, generate.sh |
| 5 |
Schemes |
scripts/compare_schemes.sh |
references/prompts/05-schemes.md |
Verified AppScheme.swift |
| 6 |
CI |
— |
references/prompts/06-ci.md |
Updated CI pipelines |
| 7 |
Cache |
scripts/extract_cache_data.sh, scripts/warm_cache.sh |
references/prompts/07-cache.md |
Optimized productTypes |
| 8 |
Validation |
scripts/compare_settings.sh, scripts/validate_migration.sh |
references/prompts/08-validation.md |
PASS/FAIL report |
Workflow
Read references/prompts/00-context.md for the full orchestration context. For each phase:
- Read the phase prompt — Load
references/prompts/0X-*.md for detailed instructions.
- Run the script (if applicable) — Execute the phase script to collect data.
- Execute the phase — Generate/modify files following the prompt instructions.
- Present results — Summarize files created, decisions made, warnings found.
- Get feedback — Ask user before proceeding to next phase.
- Validate — From phase 4 onward, verify
tuist generate succeeds and project builds.
Never skip phases or execute multiple at once without explicit user approval.
Scripts Reference
All scripts use set -euo pipefail and require mise for tool versioning. All scripts have placeholder values marked with ← Adjust comments — update them before running.
| Script |
Phase |
Purpose |
scripts/setup.sh |
Pre-migration |
Install brew, mise, and tools from .mise.toml |
scripts/audit.sh |
1 |
Collect all project data into /tmp/tuist-audit/ |
scripts/generate.sh |
4 |
tuist install + tuist generate with optional --clean |
scripts/compare_schemes.sh |
5 |
Compare schemes between original and Tuist projects |
scripts/extract_cache_data.sh |
7 |
Extract dependency graph for cache optimization |
scripts/warm_cache.sh |
7 |
Pre-compile external dependencies |
scripts/compare_settings.sh |
8 |
Compare build settings between both projects |
scripts/validate_migration.sh |
8 |
End-to-end validation with 7 checks and PASS/FAIL |
Tuist File Structure
Project root (new files)
├── .mise.toml ← Tool versions (tuist, swiftlint)
├── Project.swift ← Minimal: `let project = App.project`
├── Workspace.swift ← Root project + module paths + schemes
├── Tuist.swift ← Xcode/Swift version constraints
├── Tuist/Package.swift ← External deps + targetSettings per module
└── Tuist/ProjectDescriptionHelpers/
├── Config.swift ← App name, destinations, base settings
├── BuildConfiguration.swift ← Debug/Staging/Release configurations
├── Environment.swift ← Dev/Staging/Prod: API URLs, bundle IDs
├── Module.swift ← Struct wrapping SPM local package refs
├── Modules.swift ← Central registry of all modules
├── App.swift ← App target + UI tests target
├── AppScheme.swift ← Scheme factory per environment
└── BuildScripts.swift ← Run Script build phases (SwiftLint, etc.)
Key Rules
- All values from audit — Build settings, bundle IDs, signing, dependencies come from
AUDIT_REPORT.md, never from reference projects.
-Tuist suffix during migration — Name the project AppName-Tuist so both projects coexist. Remove suffix after validation.
targetSettings synchronizes, not overrides — Ensures Xcode build settings match what each Package.swift declares.
- Modules with
nonisolated default — Need a separate SettingsDictionary in targetSettings.
productTypes for cache — External dependencies declared as .framework get cached as pre-compiled binaries.
- Incremental validation — From phase 4, run
tuist generate after each change.
Audit to Helpers Mapping
| Tuist Helper |
Built From (Audit Section) |
Config.swift |
Build settings common to all targets |
BuildConfiguration.swift |
Build configurations (Debug/Release/Staging) |
Environment.swift |
Schemes + environment-specific values |
Module.swift |
Module list + Package.swift files |
Modules.swift |
Complete module list from targets |
App.swift |
Info.plist + resources + build phases + signing |
AppScheme.swift |
Schemes (run config, test targets, coverage) |
BuildScripts.swift |
Run Script build phases |
Tuist/Package.swift |
swiftSettings per module + external deps |
Validation Criteria
Migration is valid when ALL pass:
tuist migration check-empty-settings reports no orphaned settings
- Build settings diff shows no functional differences
xcdiff shows no missing source files or resources
- Dependency graph matches
- Full test suite passes (unit + snapshot + UI)
validate_migration.sh exits with code 0
Common Failure Patterns
.intentdefinition must go in sources, not resources
.xcstrings collides with .strings/.stringsdict globs
- ObjC categories in static frameworks need
-ObjC in OTHER_LDFLAGS
- SPM resource bundles require
.process("Resources") and Bundle.module
- Types not found → source files accidentally excluded
- Undefined symbols → missing SDK frameworks or dependency products
- Launch crashes → incorrect bundle IDs, entitlements, or resources
1---2name: tuist-migration3description: Integrates Tuist into an existing iOS project that uses SPM local packages. Use when migrating a project from a manually maintained .xcodeproj to a Tuist-generated project, adding Tuist as an orchestration layer on top of SPM. Covers 8 sequential phases — audit, base structure, helpers, generation, schemes, CI, cache, and validation. Includes automation scripts and AI prompt templates for each phase.4---56# Tuist Migration78Integrate Tuist into an existing iOS project with SPM local packages, without modifying the modules' `Package.swift` files. Tuist acts as an orchestration layer that generates the `.xcodeproj`/`.xcworkspace` from declarative Swift manifests.910## Fundamental Principle1112**Tuist does not touch modules, it only orchestrates the project that consumes them.** The `Package.swift` files remain intact. If Tuist is removed later, the modules are still functional SPM packages.1314## Reference Project1516Use the current project's Tuist configuration (`Tuist/ProjectDescriptionHelpers/`, `Project.swift`, `Workspace.swift`, `Tuist.swift`, `Tuist/Package.swift`) as the **primary reference** for API syntax and helper patterns. **Never copy** configurations, bundle IDs, modules, or dependencies — adapt patterns to the target project using audit data.1718## Migration Phases19208 sequential phases. Each has a script and/or prompt template in the bundled resources.2122| # | Phase | Script | Prompt | Output |23|---|-------|--------|--------|--------|24| 1 | Audit | `scripts/audit.sh` | `references/prompts/01-audit.md` | `AUDIT_REPORT.md` |25| 2 | Base structure | — | `references/prompts/02-base-structure.md` | `Tuist.swift`, `Tuist/Package.swift`, `.gitignore` |26| 3 | Helpers | — | `references/prompts/03-helpers.md` | `Tuist/ProjectDescriptionHelpers/*.swift` |27| 4 | Generation | `scripts/generate.sh` | `references/prompts/04-generation.md` | `Project.swift`, `Workspace.swift`, `generate.sh` |28| 5 | Schemes | `scripts/compare_schemes.sh` | `references/prompts/05-schemes.md` | Verified `AppScheme.swift` |29| 6 | CI | — | `references/prompts/06-ci.md` | Updated CI pipelines |30| 7 | Cache | `scripts/extract_cache_data.sh`, `scripts/warm_cache.sh` | `references/prompts/07-cache.md` | Optimized `productTypes` |31| 8 | Validation | `scripts/compare_settings.sh`, `scripts/validate_migration.sh` | `references/prompts/08-validation.md` | PASS/FAIL report |323334## Workflow3536Read `references/prompts/00-context.md` for the full orchestration context. For each phase:37381. **Read the phase prompt** — Load `references/prompts/0X-*.md` for detailed instructions.392. **Run the script** (if applicable) — Execute the phase script to collect data.403. **Execute the phase** — Generate/modify files following the prompt instructions.414. **Present results** — Summarize files created, decisions made, warnings found.425. **Get feedback** — Ask user before proceeding to next phase.436. **Validate** — From phase 4 onward, verify `tuist generate` succeeds and project builds.4445**Never skip phases or execute multiple at once without explicit user approval.**4647## Scripts Reference4849All scripts use `set -euo pipefail` and require `mise` for tool versioning. **All scripts have placeholder values marked with `← Adjust` comments** — update them before running.5051| Script | Phase | Purpose |52|--------|-------|---------|53| `scripts/setup.sh` | Pre-migration | Install brew, mise, and tools from `.mise.toml` |54| `scripts/audit.sh` | 1 | Collect all project data into `/tmp/tuist-audit/` |55| `scripts/generate.sh` | 4 | `tuist install` + `tuist generate` with optional `--clean` |56| `scripts/compare_schemes.sh` | 5 | Compare schemes between original and Tuist projects |57| `scripts/extract_cache_data.sh` | 7 | Extract dependency graph for cache optimization |58| `scripts/warm_cache.sh` | 7 | Pre-compile external dependencies |59| `scripts/compare_settings.sh` | 8 | Compare build settings between both projects |60| `scripts/validate_migration.sh` | 8 | End-to-end validation with 7 checks and PASS/FAIL |6162## Tuist File Structure6364```65Project root (new files)66├── .mise.toml ← Tool versions (tuist, swiftlint)67├── Project.swift ← Minimal: `let project = App.project`68├── Workspace.swift ← Root project + module paths + schemes69├── Tuist.swift ← Xcode/Swift version constraints70├── Tuist/Package.swift ← External deps + targetSettings per module71└── Tuist/ProjectDescriptionHelpers/72 ├── Config.swift ← App name, destinations, base settings73 ├── BuildConfiguration.swift ← Debug/Staging/Release configurations74 ├── Environment.swift ← Dev/Staging/Prod: API URLs, bundle IDs75 ├── Module.swift ← Struct wrapping SPM local package refs76 ├── Modules.swift ← Central registry of all modules77 ├── App.swift ← App target + UI tests target78 ├── AppScheme.swift ← Scheme factory per environment79 └── BuildScripts.swift ← Run Script build phases (SwiftLint, etc.)80```8182## Key Rules83841. **All values from audit** — Build settings, bundle IDs, signing, dependencies come from `AUDIT_REPORT.md`, never from reference projects.852. **`-Tuist` suffix during migration** — Name the project `AppName-Tuist` so both projects coexist. Remove suffix after validation.863. **`targetSettings` synchronizes, not overrides** — Ensures Xcode build settings match what each `Package.swift` declares.874. **Modules with `nonisolated` default** — Need a separate `SettingsDictionary` in `targetSettings`.885. **`productTypes` for cache** — External dependencies declared as `.framework` get cached as pre-compiled binaries.896. **Incremental validation** — From phase 4, run `tuist generate` after each change.9091## Audit to Helpers Mapping9293| Tuist Helper | Built From (Audit Section) |94|---|---|95| `Config.swift` | Build settings common to all targets |96| `BuildConfiguration.swift` | Build configurations (Debug/Release/Staging) |97| `Environment.swift` | Schemes + environment-specific values |98| `Module.swift` | Module list + Package.swift files |99| `Modules.swift` | Complete module list from targets |100| `App.swift` | Info.plist + resources + build phases + signing |101| `AppScheme.swift` | Schemes (run config, test targets, coverage) |102| `BuildScripts.swift` | Run Script build phases |103| `Tuist/Package.swift` | `swiftSettings` per module + external deps |104105## Validation Criteria106107Migration is valid when ALL pass:1081. `tuist migration check-empty-settings` reports no orphaned settings1092. Build settings diff shows no functional differences1103. `xcdiff` shows no missing source files or resources1114. Dependency graph matches1125. Full test suite passes (unit + snapshot + UI)1136. `validate_migration.sh` exits with code 0114115## Common Failure Patterns116117- `.intentdefinition` must go in sources, not resources118- `.xcstrings` collides with `.strings`/`.stringsdict` globs119- ObjC categories in static frameworks need `-ObjC` in `OTHER_LDFLAGS`120- SPM resource bundles require `.process("Resources")` and `Bundle.module`121- Types not found → source files accidentally excluded122- Undefined symbols → missing SDK frameworks or dependency products123- Launch crashes → incorrect bundle IDs, entitlements, or resources