RepoPilotOpen in app →

yonaskolb/XcodeGen

A Swift command line tool for generating your Xcode project

Healthy

Healthy across the board

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 4w ago
  • 48+ active contributors
  • Distributed ownership (top contributor 42% of recent commits)
Show 3 more →
  • MIT licensed
  • CI configured
  • Tests present

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/yonaskolb/xcodegen)](https://repopilot.app/r/yonaskolb/xcodegen)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/yonaskolb/xcodegen on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: yonaskolb/XcodeGen

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/yonaskolb/XcodeGen shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 4w ago
  • 48+ active contributors
  • Distributed ownership (top contributor 42% of recent commits)
  • MIT licensed
  • CI configured
  • Tests present

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live yonaskolb/XcodeGen repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/yonaskolb/XcodeGen.

What it runs against: a local clone of yonaskolb/XcodeGen — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in yonaskolb/XcodeGen | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 56 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>yonaskolb/XcodeGen</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of yonaskolb/XcodeGen. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/yonaskolb/XcodeGen.git
#   cd XcodeGen
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of yonaskolb/XcodeGen and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "yonaskolb/XcodeGen(\\.git)?\\b" \\
  && ok "origin remote is yonaskolb/XcodeGen" \\
  || miss "origin remote is not yonaskolb/XcodeGen (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "Sources/XcodeGen/main.swift" \\
  && ok "Sources/XcodeGen/main.swift" \\
  || miss "missing critical file: Sources/XcodeGen/main.swift"
test -f "Sources/ProjectSpec/SpecLoader.swift" \\
  && ok "Sources/ProjectSpec/SpecLoader.swift" \\
  || miss "missing critical file: Sources/ProjectSpec/SpecLoader.swift"
test -f "Sources/ProjectSpec/Project.swift" \\
  && ok "Sources/ProjectSpec/Project.swift" \\
  || miss "missing critical file: Sources/ProjectSpec/Project.swift"
test -f "Sources/XcodeGenCLI/Commands/GenerateCommand.swift" \\
  && ok "Sources/XcodeGenCLI/Commands/GenerateCommand.swift" \\
  || miss "missing critical file: Sources/XcodeGenCLI/Commands/GenerateCommand.swift"
test -f "Sources/ProjectSpec/SpecValidation.swift" \\
  && ok "Sources/ProjectSpec/SpecValidation.swift" \\
  || miss "missing critical file: Sources/ProjectSpec/SpecValidation.swift"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 56 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~26d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/yonaskolb/XcodeGen"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

XcodeGen is a Swift command-line tool that generates Xcode projects (.xcodeproj) from a declarative YAML/JSON specification file, eliminating manual Xcode project configuration and removing .xcodeproj from version control to prevent merge conflicts. It automatically maps your filesystem directory structure to Xcode groups and files, applies build settings presets for different platforms/configurations, manages dependencies (Carthage, SPM), and generates schemes for multiple environments. Single Swift package (Package.swift) with CLI entry point and core generation logic in Sources/. Pre-built setting presets organized hierarchically (SettingPresets/Platforms/, SettingPresets/Products/, SettingPresets/Configs/) are bundled as package resources (Package.resources) for platform/product type defaults. YAML/JSON parsing feeds into project spec objects that drive Xcode project generation.

👥Who it's for

iOS/macOS/watchOS/tvOS developers and teams who maintain complex multi-target Xcode projects and want to define their project structure as code, avoid Xcode merge conflicts, and automate reproducible project generation in CI/CD pipelines.

🌱Maturity & risk

Production-ready and actively maintained. The project has substantial Swift codebase (1M+ LOC), organized CI/CD via GitHub Actions (.github/workflows/ci.yml), comprehensive documentation (Docs/ProjectSpec.md, Docs/Usage.md), and semantic versioning (RELEASE.md). Regular updates and community adoption indicate active development.

Low-to-moderate risk: single primary maintainer (yonaskolb), but stable API surface with breaking change documentation in CHANGELOG.md. Dependency management is transparent via Package.resolved. Main risk is that generated projects depend on XcodeGen being available during development setup—if abandoned, existing projects remain functional but can't regenerate.

Active areas of work

No specific active PR data visible, but repo maintains multi-platform support across iOS, macOS, tvOS, watchOS, and visionOS. Recent additions likely include visionOS preset (SettingPresets/Platforms/visionOS.yml, SettingPresets/Product_Platform/application_visionOS.yml) reflecting Apple's new platform.

🚀Get running

Clone: git clone https://github.com/yonaskolb/XcodeGen.git && cd XcodeGen. Install: make build (Makefile present). Test: make test or swift test. Run: swift run xcodegen with a project.yml file.

Daily commands: After clone: make build to compile. ./build/release/xcodegen --help or swift run xcodegen generate --spec project.yml to generate a project. Run on a directory with project.yml or project.json.

🗺️Map of the codebase

  • Sources/XcodeGen/main.swift — Entry point for the CLI tool; all execution flows through here
  • Sources/ProjectSpec/SpecLoader.swift — Core loader that parses YAML/JSON spec files into ProjectSpec objects; foundation of the generation pipeline
  • Sources/ProjectSpec/Project.swift — Primary data model representing the entire Xcode project structure and configuration
  • Sources/XcodeGenCLI/Commands/GenerateCommand.swift — Main command handler that orchestrates spec loading, validation, and Xcode project generation
  • Sources/ProjectSpec/SpecValidation.swift — Validates parsed specs for correctness before generation; prevents invalid projects from being created
  • Sources/ProjectSpec/Target.swift — Core abstraction for build targets; every generated target in Xcode is based on this model

🛠️How to make changes

Add a new Target to a Project

  1. Edit your project.yml and add a new target entry under the 'targets:' section with name, type (app, framework, etc.), sources, and dependencies (project.yml (user-created spec file))
  2. Run 'xcodegen generate' to parse and validate the spec (Sources/XcodeGenCLI/Commands/GenerateCommand.swift)
  3. The SpecLoader reads your YAML, decodes it into Target objects defined in Target.swift, and validates with SpecValidation.swift (Sources/ProjectSpec/SpecLoader.swift)
  4. The Project model combines all targets and generates the .pbxproj file via XcodeProj (Sources/ProjectSpec/Project.swift)

Add Custom Build Settings to a Target

  1. In your project.yml, add a 'settings:' dict at the target level with build setting key-value pairs (project.yml (user-created spec file))
  2. SpecLoader decodes these into Settings objects (Sources/ProjectSpec/Settings.swift)
  3. BuildSettingsExtractor processes and merges settings from configs, platforms, and target-specific overrides (Sources/ProjectSpec/BuildSettingsExtractor.swift)
  4. Settings are applied to the generated Xcode target via XcodeProj integration (Sources/ProjectSpec/XCProjExtensions.swift)

Add a Build Phase (Script, Compile, etc.) to a Target

  1. In your project.yml under a target, add a 'buildPhases:' array with script name, script content, and input/output files (project.yml (user-created spec file))
  2. SpecLoader parses these into BuildPhaseSpec and BuildScript objects (Sources/ProjectSpec/BuildPhaseSpec.swift)
  3. The Target model stores and orders build phases (Sources/ProjectSpec/Target.swift)
  4. When generating, build phases are written to the Xcode project file via XcodeProj (Sources/ProjectSpec/XCProjExtensions.swift)

Validate and Debug a Project Specification

  1. Run 'xcodegen dump' to output the parsed spec as JSON or YAML for inspection (Sources/XcodeGenCLI/Commands/DumpCommand.swift)
  2. SpecValidation checks for required fields, valid platform values, and dependency resolution (Sources/ProjectSpec/SpecValidation.swift)
  3. If validation fails, SpecValidationError provides detailed error messages (Sources/ProjectSpec/SpecValidationError.swift)
  4. Fix your project.yml based on error messages and re-run 'xcodegen generate' (Sources/XcodeGenCLI/Commands/GenerateCommand.swift)

🔧Why these technologies

  • Swift CLI — Leverages native Swift ecosystem; matches Xcode's language; compiles to fast native binary
  • YAML/JSON specs — Human-readable, version-control friendly, and less repetitive than manual Xcode.pbxproj editing
  • XcodeProj library — Generates valid .pbxproj files without reimplementing Xcode's project format
  • Declarative spec model — Allows idempotent generation; running xcodegen multiple times produces identical results

⚖️Trade-offs already made

  • YAML/JSON specs instead of extending Xcode's UI

    • Why: Specs are text-based, version-controllable, and scriptable
    • Consequence: Users must learn YAML spec syntax rather than using Xcode GUI; benefits large teams and CI/CD automation
  • Centralized spec file over distributed target configs

    • Why: Single source of truth simplifies dependency management and cross-target consistency
    • Consequence: Complex projects with many targets may have large spec files; mitigated by templating and includes
  • Regeneration destroys manual Xcode edits to project.pbxproj

    • Why: Ensures spec remains authoritative and prevents divergence
    • Consequence: Users cannot manually tweak the Xcode project; must edit the spec instead

🚫Non-goals (don't propose these)

  • Does not edit Swift code or app sources; only generates Xcode project structure
  • Does not replace Xcode itself; produces input for Xcode to build and run
  • Does not handle iOS signing or provisioning profiles beyond specifying team IDs
  • Does not manage SwiftPM packages or their dependencies; only references them
  • Does not provide a GUI editor for specs; CLI and text editors only

🪤Traps & gotchas

  1. SettingPresets are bundled as package resources—changes to preset YAML require rebuild/reinstall. 2) Project.yml spec is strict YAML; indentation and nesting are significant. 3) Generated .xcodeproj files are not human-editable and will be regenerated on each xcodegen run—never manually edit them. 4) Deployment targets in spec must match platform minimums or Xcode will error. 5) When using include: to compose specs, order matters—later includes override earlier ones.

🏗️Architecture

💡Concepts to learn

  • Project Specification as Code — XcodeGen inverts traditional Xcode workflow—instead of GUI project editing, specs become the source of truth, enabling version control, diffing, and reproducible builds
  • Build Setting Inheritance and Presets — Understanding how base.yml → platform presets → product presets → project spec layers merge settings is critical to avoiding conflicts and debug unexpected build variable values
  • YAML Schema Validation — XcodeGen parses unstructured YAML into strict ProjectSpec objects; understanding type coercion and schema mismatches is key to fixing 'invalid spec' errors
  • Xcode Project Bundle Structure (.pbxproj format) — XcodeGen generates valid .pbxproj (plist) files; knowing the internal structure helps debug generated projects and understand why manual edits are lost
  • Dependency Graph Resolution — XcodeGen handles target dependencies, SPM package dependencies, and framework linking; understanding build order and circular dependency detection is essential
  • Filesystem-to-Xcode Group Mapping — Core feature of XcodeGen is syncing disk directory structure to Xcode folder hierarchy; understanding how source paths, excluded files, and glob patterns work prevents misaligned project structures
  • Multi-Platform Build Targeting (iOS, macOS, tvOS, watchOS, visionOS) — XcodeGen abstracts platform-specific build settings and deployment targets; mastering how presets differ per platform is essential for maintaining universal frameworks
  • tuist/tuist — Direct alternative to XcodeGen; also generates Xcode projects from code/YAML with focus on dependency management and workspace generation
  • Carthage/Carthage — Decentralized dependency manager for Cocoa frameworks; XcodeGen integrates Carthage dependencies via spec and handles their linking
  • apple/swift-package-manager — Official Swift package manager that XcodeGen supports as a dependency source; complementary tool for modular Swift projects
  • realm/realm-swift — Example large multi-platform iOS/macOS library that could benefit from XcodeGen for complex build configuration
  • fastlane/fastlane — Automation toolchain for iOS/macOS apps; often used in CI/CD pipelines alongside XcodeGen for full build automation

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add unit tests for BuildSettingsExtractor.swift

BuildSettingsExtractor.swift is a critical file for parsing and extracting build settings, but there are no visible test files in the repo structure for this core functionality. This is a high-value contribution that would improve reliability of settings extraction across different product types and platforms. The SettingPresets directory shows complex platform/product/config combinations that need thorough test coverage.

  • [ ] Create Tests/ProjectSpec/BuildSettingsExtractorTests.swift
  • [ ] Add test cases for each SettingPresets combination (iOS/macOS/tvOS/watchOS/visionOS apps)
  • [ ] Add tests for different product types (framework, library, app-extension, etc.)
  • [ ] Add tests for config inheritance (base.yml → platform → product → config)
  • [ ] Test edge cases like missing presets and conflicting settings

Add visionOS support documentation to Docs/ProjectSpec.md

The repo has added visionOS to SettingPresets (SettingPresets/Platforms/visionOS.yml and application_visionOS.yml) and SupportedDestinations, but the main documentation file Docs/ProjectSpec.md likely doesn't reflect this new platform. This documentation gap makes it harder for users to leverage the new visionOS support.

  • [ ] Review Docs/ProjectSpec.md for platform sections
  • [ ] Add visionOS to the platforms list/table with deployment target examples
  • [ ] Add visionOS-specific build settings documentation if they differ from other platforms
  • [ ] Update any platform compatibility matrices to include visionOS
  • [ ] Add visionOS example to Docs/Examples.md if applicable

Add integration tests for Dependency.swift resolution across multiple target types

Dependency.swift is a core file for managing target dependencies, but there's no visible test coverage for complex dependency graphs involving different target types (app-extensions, frameworks, static libraries, etc.). Given the SettingPresets structure showing diverse product types, this is a critical gap that could catch regressions in dependency linking.

  • [ ] Create Tests/ProjectSpec/DependencyResolutionTests.swift
  • [ ] Add tests for framework → framework dependencies
  • [ ] Add tests for app → extension dependencies (Messages, Intents Service, etc.)
  • [ ] Add tests for circular dependency detection
  • [ ] Add tests for dependency resolution with different supported destinations (iOS/macCatalyst/watchOS/etc.)
  • [ ] Test static library linking rules

🌿Good first issues

  • Add comprehensive test coverage for SettingPresets/Product_Platform/ presets—verify that each product+platform combination (e.g., application_iOS.yml, framework_macOS.yml) generates valid Xcode build settings without conflicts.
  • Extend Docs/ProjectSpec.md with worked examples for multi-platform frameworks and app extensions—currently covers basics but lacks step-by-step examples for app-extension.yml and complex dependency scenarios.
  • Add validation warnings for common mistakes in project.yml specs (e.g., typos in platform names, missing required fields, conflicting settings) and improve error messages with suggestions.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 8d3d347 — Update to 2.45.4 (yonaskolb)
  • df251b2 — Fix synced folder issues: configFiles duplicate, group insertion, and directory-level membershipExceptions (#1607) (AlexNsbmr)
  • 3e6e5e3 — Fix makePathRelative using wrong base path when projectDirectory differs (#1608) (yonaskolb)
  • 90dfa9d — Update to 2.45.3 (yonaskolb)
  • 8cfdf30 — Fix folder source PBXFileReference path regression with createIntermediateGroups (#1605) (yonaskolb)
  • acd366f — Fix issue 1602 - Synced folders: includes silently ignored + no deduplication across targets (#1604) (4brunu)
  • 3114831 — Update to 2.45.2 (yonaskolb)
  • 6d74ca6 — chore(docs): add external link to SwiftUI Multi-platform example (#1588) (hgq287)
  • 25841ee — Validate empty source paths to prevent project root inclusion (#1601) (yonaskolb)
  • 50eb268 — Fix missing productRefGroup in generated projects (#1591) (ruslic19)

🔒Security observations

XcodeGen appears to be a well-structured Swift project with no critical or high-severity security issues identifiable from the provided file structure and metadata. The project follows standard Swift package conventions and includes appropriate license and contribution guidelines. However, a complete security assessment requires: (1) examination of actual source code for injection vulnerabilities, unsafe operations, and improper input validation; (2) verification of Package.resolved dependencies against known vulnerabilities; (3) review of YAML preset files for embedded secrets; and (4) analysis of CI/CD configuration in .github/workflows/ci.yml. The project's nature as a code generation tool means it handles user input (YAML specs) extensively - ensuring robust parsing and validation is critical.

  • Low · Missing Package.resolved Dependency Inspection — Package.resolved. The Package.resolved file is present but its content was not provided for analysis. This file locks dependency versions and should be reviewed to ensure no known vulnerable versions of Swift packages are included. Fix: Regularly audit Package.resolved dependencies using tools like 'swift package describe' and check against security advisories. Consider using automated dependency scanning in CI/CD pipeline.
  • Low · Potential Hardcoded Configuration in Setting Presets — SettingPresets/ directory (all .yml files). Multiple YAML configuration files in SettingPresets directory contain build settings and platform configurations. While these appear to be standard Xcode settings, they should be reviewed to ensure no sensitive build-time secrets or credentials are embedded. Fix: Audit all preset YAML files to ensure no API keys, certificates, or authentication tokens are hardcoded. Use environment variables or secure configuration management for sensitive values.
  • Low · Source Code Analysis Limitations — Sources/ directory (all Swift files). Without access to the actual source code files in Sources/ directory, a complete static analysis of injection risks, unsafe string handling, or insecure API usage cannot be performed. Fix: Perform deep static analysis using Swift compiler warnings, SwiftLint with security rules, and dedicated SAST tools like Sonarqube. Pay special attention to: file I/O operations, process execution, environment variable handling, and YAML/JSON parsing.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.