Best practices for Tuist project generation and modular iOS/watchOS architecture. Use when working with Tuist manifests (Project.swift, Workspace.swift, Tuist.swift), generating Xcode projects, declaring targets, managing dependencies, or building with xcodebuild in Tuist projects.
Guide AI agents through Tuist project generation, target declaration, dependency management, and modular architecture. Report only genuine problems — do not nitpick or invent issues.
When working on a Tuist project:
references/manifests.md.references/targets.md.references/dependencies.md.references/modular-architecture.md.references/build-and-ci.md.references/resources.md.references/helpers.md.If doing a partial task, load only the relevant reference files.
# Generate Xcode project (always use --no-open in agents/CI)
tuist generate --no-open
# Install external dependencies first (REQUIRED before generate if using .external)
tuist install
# Edit manifests in Xcode (opens Project.swift, Tuist.swift, etc.)
tuist edit
# Build
tuist build
# Clean derived data and caches
tuist clean
tuist install before tuist generate if the project uses external (remote) dependencies.--no-open to tuist generate when running in an agent or CI environment.buildableFolders on targets to avoid regenerating the project when files are added or removed.SWIFT_STRICT_CONCURRENCY: "complete".CODE_SIGN_IDENTITY: ""..target(
name: "MyApp",
destinations: [.iPhone],
product: .app,
bundleId: "com.example.app",
deploymentTargets: .iOS("18.0"),
infoPlist: .extendingDefault(with: [
"CFBundleDisplayName": "My App",
"UILaunchScreen": [:],
]),
sources: ["Sources/**"],
resources: ["Resources/**"],
buildableFolders: ["Sources/", "Resources/"],
dependencies: [
.target(name: "SharedKit"),
],
settings: .settings(
base: [
"SWIFT_VERSION": "6.0",
"SWIFT_STRICT_CONCURRENCY": "complete",
]
)
)
// 1. Internal target in same Project.swift
.target(name: "SharedKit")
// 2. Local SPM package (declared in project packages: [])
.package(product: "CPCore")
// 3. External/remote SPM package (declared in Tuist.swift)
.external(name: "Alamofire")
// 4. Apple SDK framework
.sdk(name: "HealthKit", type: .framework)
// 5. Local binary / XCFramework
.xcframework(path: "Frameworks/Analytics.xcframework")
Feature modules depend DOWN on shared kit, NEVER sideways on other features:
App → FeatureA, FeatureB, SharedKit
FeatureA → SharedKit (NEVER → FeatureB)
FeatureB → SharedKit (NEVER → FeatureA)
SharedKit → (no internal deps)
tuist install — external deps won't resolve without it..package(product:) for internal targets — use .target(name:) instead..target(name:) for local SPM packages — use .package(product:) and declare the package in packages: [.local(path: "...")].--no-open — Xcode launches in headless CI/agent environments, causing hangs.CODE_SIGN_IDENTITY: "" for CI builds..iOS("18.0") for single-platform, .multiplatform(iOS: "18.0", watchOS: "11.0") for multi-platform targets..dictionary([...]) inline, not a file reference, for agent-generated targets.