DEV Community

ArshTechPro
ArshTechPro

Posted on

Getting Started with Tuist: Manage iOS Projects with ease

What is Tuist?

Tuist is a command-line tool that helps you generate, maintain, and interact with Xcode projects at scale. Unlike package managers like CocoaPods or Swift Package Manager that manage dependencies, Tuist manages your Xcode project configuration itself.

Instead of dealing with complex .xcodeproj files that are prone to merge conflicts and hard to maintain, Tuist lets you define your entire project structure in simple Swift files. Think of it as "Infrastructure as Code" but for iOS projects.

Why Use Tuist?

1. No More Merge Conflicts

.xcodeproj files are XML-based and notoriously difficult to merge. With Tuist, you define your project in Project.swift using Swift code, which is much easier to review and merge.

2. Consistency Across Teams

Everyone on your team generates the same project configuration from the same manifest files.

3. Easier Modularization

Tuist makes it simple to break your app into multiple modules and frameworks, improving build times and code organization.

4. Build Time Optimization

Tuist can cache compiled frameworks and share them across team members, dramatically reducing build times.

5. Cleaner Git History

You can .gitignore the generated .xcodeproj and .xcworkspace files, keeping only the manifest files in version control.

When Should You Use Tuist?

Use Tuist if:

  • You work on medium to large projects
  • You have a team where merge conflicts are common
  • You want to modularize your app
  • You're starting a new project and want to set it up right

Installation

Install Tuist using Homebrew:

brew install tuist
Enter fullscreen mode Exit fullscreen mode

Or using the official installer:

curl -Ls https://install.tuist.io | bash
Enter fullscreen mode Exit fullscreen mode

Verify the installation:

tuist --version
Enter fullscreen mode Exit fullscreen mode

Creating Your First Tuist Project

Let's build a simple iOS app with MVVM architecture using Tuist.

Step 1: Initialize a New Project

# Create a directory for your project
mkdir MyTuistApp
cd MyTuistApp

# Initialize Tuist
tuist init
Enter fullscreen mode Exit fullscreen mode

Tuist will ask you a few questions:

  • Name: Enter your app name (e.g., "MyApp")
  • Platform: Select iOS
  • Server: Choose No for now

This creates:

  • Project.swift - Your project configuration
  • Tuist/ - Tuist configuration folder
  • A basic folder structure

Step 2: Navigate to Your Project

cd MyApp  # Navigate into the generated folder
Enter fullscreen mode Exit fullscreen mode

Step 3: Create Your Folder Structure

# Create organized directories for MVVM
mkdir -p Sources/App
mkdir -p Sources/Models
mkdir -p Sources/ViewModels
mkdir -p Sources/Views
mkdir -p Resources/Assets.xcassets
mkdir -p Tests
Enter fullscreen mode Exit fullscreen mode

Step 4: Update Project.swift

Replace the contents of Project.swift with:

import ProjectDescription

let project = Project(
    name: "MyApp",
    targets: [
        .target(
            name: "MyApp",
            destinations: .iOS,
            product: .app,
            bundleId: "com.example.myapp",
            infoPlist: .extendingDefault(
                with: [
                    "UILaunchScreen": [:],
                ]
            ),
            sources: ["Sources/**"],
            resources: ["Resources/**"],
            dependencies: []
        ),
        .target(
            name: "MyAppTests",
            destinations: .iOS,
            product: .unitTests,
            bundleId: "com.example.myapp.tests",
            infoPlist: .default,
            sources: ["Tests/**"],
            dependencies: [
                .target(name: "MyApp")
            ]
        )
    ]
)
Enter fullscreen mode Exit fullscreen mode

Step 5: Create the App Entry Point

Create Sources/App/MyAppApp.swift:

import SwiftUI

@main
struct MyAppApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 6: Create Your Source Files

Create Sources/Models/User.swift:

import Foundation

struct User: Identifiable {
    let id = UUID()
    let name: String
}
Enter fullscreen mode Exit fullscreen mode

Create Sources/ViewModels/ContentViewModel.swift:

import Foundation

class ContentViewModel: ObservableObject {
    @Published var greeting = "Hello from Tuist!"
}
Enter fullscreen mode Exit fullscreen mode

Create Sources/Views/ContentView.swift:

import SwiftUI

struct ContentView: View {
    @StateObject private var viewModel = ContentViewModel()

    var body: some View {
        VStack {
            Text(viewModel.greeting)
                .font(.largeTitle)
                .padding()
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 7: Generate and Run

Now generate your Xcode project:

tuist generate
Enter fullscreen mode Exit fullscreen mode

This will:

  1. Read your Project.swift configuration
  2. Generate the .xcodeproj file
  3. Automatically open it in Xcode

Press ⌘ + R to build and run your app!

Project Structure

Your final structure should look like this:

MyApp/
├── Project.swift          # Project configuration
├── Tuist/                 # Tuist settings
│   └── Config.swift
├── Sources/
│   ├── App/
│   │   └── MyAppApp.swift
│   ├── Models/
│   │   └── User.swift
│   ├── ViewModels/
│   │   └── ContentViewModel.swift
│   └── Views/
│       └── ContentView.swift
├── Resources/
│   └── Assets.xcassets/
└── Tests/
    └── MyAppTests.swift
Enter fullscreen mode Exit fullscreen mode

Common Tuist Commands

# Initialize a new project
tuist init

# Generate Xcode project
tuist generate

# Clean generated files
tuist clean

# Edit project manifests in Xcode
tuist edit

# Visualize project dependencies
tuist graph

# Get help
tuist --help
Enter fullscreen mode Exit fullscreen mode

Key Benefits in Practice

Before Tuist:

  • Manual Xcode project configuration
  • Frequent merge conflicts in .xcodeproj
  • Inconsistent project setup across team
  • Hard to refactor or modularize

After Tuist:

  • Project defined in Swift code
  • Easy code reviews for project changes
  • Consistent project generation
  • Simple modularization and scaling

gitignore Configuration

Add these to your .gitignore:

# Tuist generated files
*.xcodeproj
*.xcworkspace
Derived/

# Keep Tuist manifests
!Tuist/
Enter fullscreen mode Exit fullscreen mode

Conclusion

By defining your project as code, you gain consistency, reduce conflicts, and make scaling easier.

Whether you're starting a new project or looking to improve an existing one, Tuist provides the tools to manage complexity as your app grows.

Top comments (1)

Collapse
 
arshtechpro profile image
ArshTechPro

.xcodeproj files are XML-based and notoriously difficult to merge. With Tuist, you define your project in Project.swift using Swift code, which is much easier to review and merge.