Skip to main content

Overview

Dependencies in Tuist can be internal (between your own targets) or external (third-party packages and frameworks). Tuist provides a robust dependency management system that validates your dependency graph and prevents common issues.

Why Tuist’s Approach is Different

Unlike Xcode projects where dependency graphs can be error-prone and implicit, Tuist makes dependencies explicit and static. This enables:
  • Validation: Automatic detection of cycles and invalid dependencies
  • Optimization: Binary caching and selective testing
  • Consistency: Guaranteed correct linking and embedding
  • Simplicity: Focus on what depends on what, not implementation details
Tuist automatically handles complex details like transitive dynamic dependencies, static XCFramework processing, and proper linking configurations.

Internal Dependencies

Internal dependencies are connections between targets in your project.

Dependency Types

When defining a target, use the dependencies parameter with these types:

Conditional Dependencies

Link dependencies only for specific platforms:
Project.swift

Dependency Graph Best Practices

Layered Architecture

Organize dependencies in clear layers:
Avoid circular dependencies. Tuist validates the dependency graph and will error if cycles are detected.

Visualize Your Graph

Use Tuist’s graph command to understand dependencies:

External Dependencies

Tuist supports multiple ways to integrate external dependencies. Swift Packages are the recommended approach for external dependencies.

XcodeProj-Based Integration

Tuist’s default integration method provides more control and enables caching:

Xcode’s Default Integration

For simpler projects or when you need Xcode’s native SPM integration:
Project.swift
Dependency types:
  • .runtime - Standard dependency
  • .macro - Swift macros
  • .plugin - Build tool plugins
SPM build tool plugins must use Xcode’s default integration, even when using XcodeProj-based integration for other dependencies.

Build Tool Plugin Example

Project.swift

Binary Targets

Include binary frameworks directly in Package.swift:
Tuist/Package.swift
Reference like any other external dependency:

Carthage

Integrate Carthage dependencies as frameworks:
Ensure Carthage dependencies are present before running xcodebuild or tuist test.

CocoaPods

Integrate CocoaPods after generating the project:
CocoaPods dependencies are incompatible with Tuist’s build, test, binary caching, and selective testing features.

Static vs Dynamic Linking

The choice between static and dynamic linking significantly impacts app size and boot time.

General Guidelines

  • Release builds: Link as much as possible statically for fast boot times
  • Debug builds: Link as much as possible dynamically for fast iteration

Configuring Linking Type

Use environment variables to change linking at generation time:
Project.swift
Generate with different linking:

Special Scenarios

Apps with Extensions

Shared code between app and extensions should be dynamic to avoid duplication:
Project.swift

Static Side Effects

Tuist warns about “static side effects” - when a static target is linked transitively through dynamic targets. This can increase binary size or cause runtime crashes.

Troubleshooting

Objective-C Dependencies

Objective-C dependencies may require the -ObjC linker flag:
Project.swift

Firebase and Google Libraries

Add -ObjC Flag

Project.swift

Configure FBLPromises

Set FBLPromises to dynamic framework:
Tuist/Package.swift

The Composable Architecture

Link all TCA dependencies dynamically:
Tuist/Package.swift
With this configuration, import SwiftSharing instead of Sharing.

Transitive Static Dependencies

When a dynamic framework depends on static ones, use internal import (Swift 6+):
For older Swift versions, use @_implementationOnly:

Dependencies Not Resolving

Best Practices

On CI: Force Resolved Versions

Ensure deterministic builds:
CI Script

Keep Dependencies Updated

Regularly update and test:

Version Pinning Strategy

Tuist/Package.swift

Document Special Configurations

Create a DEPENDENCIES.md file:
DEPENDENCIES.md

Next Steps

Optimize Builds

Enable binary caching for faster builds

Project Structure

Learn how to organize your dependency graph

Set Up CI/CD

Configure CI for dependency management

Migrate from Xcode

Migrate existing dependencies to Tuist