What Build Tools Does Bitchat Use? A Complete Guide to the Swift Development Pipeline

Bitchat uses Swift Package Manager as its primary dependency manager, Xcode with xcodebuild for native iOS/macOS compilation, and three specialized tools—Just for task automation, SwiftLint for style enforcement, and Periphery for dead-code analysis—coordinated through GitHub Actions CI.

The Bitchat repository is a native Swift application for iOS and macOS that demonstrates modern Apple ecosystem development practices. This guide examines each build tool used in the project, where it is configured, and how developers interact with it during daily workflows.

Swift Package Manager: Dependency Management and Compilation

Swift Package Manager (SPM) serves as the foundation of Bitchat's build system. It declares Swift modules, library targets, and external dependencies in a single manifest file.

The Package.swift file at the repository root defines:

  • Package metadata and platform requirements
  • Internal targets and their dependencies
  • External package dependencies fetched from remote repositories
  • Build settings for each target

Developers can compile the project directly without Xcode using standard SPM commands:


# Compile in debug mode (default)

swift build

# Build optimized release binary

swift build -c release

# Run the test suite

swift test

SPM integrates seamlessly with Xcode, which detects the package manifest automatically. The Package.resolved file locks dependency versions for reproducible builds across environments.

Xcode and xcodebuild: Native App Bundling

While SPM handles compilation, Xcode remains essential for producing the final .app bundle. The bitchat.xcodeproj directory contains the full Xcode project configuration, with project.pbxproj storing build settings, code signing identities, entitlements, and target definitions.

Key files in the Xcode project:

File Purpose
bitchat.xcodeproj/project.pbxproj Primary project definition with targets and build phases
Configs/Debug.xcconfig Debug build configuration constants
Configs/Release.xcconfig Release build configuration
Configs/Local.xcconfig Local development overrides

The .xcconfig files inject build-time values such as API endpoints and feature flags. This pattern keeps secrets and environment-specific settings out of version-controlled source code.

Command-line builds using xcodebuild enable CI automation without GUI dependencies:


# Build the iOS app for device

xcodebuild -project bitchat.xcodeproj -scheme Bitchat -destination 'generic/platform=iOS' build

# Archive for App Store distribution

xcodebuild -project bitchat.xcodeproj -scheme Bitchat -configuration Release archive

Just: Task Automation for Developers

Just is a command runner that simplifies common development tasks. The Justfile at repository root defines named recipes that wrap complex shell sequences into single commands.

View available tasks:

just

Execute a defined task:


# Example: clean build as defined in the Justfile

just clean-build

The Justfile typically encapsulates operations like:

  • Cleaning build artifacts across SPM and Xcode
  • Regenerating asset catalogs
  • Running local test suites
  • Preparing release builds

Using Just reduces cognitive load—developers memorize task names rather than verbose command sequences.

SwiftLint: Enforcing Code Style

SwiftLint maintains consistent code style across the codebase. It analyzes Swift source files against rules defined in .swiftlint.yml and reports violations.

Run linting locally:


# Lint all Swift files using project configuration

swiftlint lint --config .swiftlint.yml

# Auto-correct violations where possible

swiftlint --fix --config .swiftlint.yml

The .swiftlint.yml configuration typically includes:

  • Disabled rules (e.g., trailing_whitespace)
  • Rule customizations (line length limits, identifier naming)
  • Excluded directories (generated code, dependencies)
  • Custom rule definitions

SwiftLint runs automatically in CI, blocking merges that introduce style violations.

Periphery: Dead Code Detection

Periphery performs static analysis to identify unused declarations—classes, functions, properties, and parameters that contribute to technical debt. Its configuration in .periphery.yml specifies:

  • Source directories to scan
  • Indexing build targets
  • Retention rules for false-positive suppression

Execute dead-code analysis:

periphery scan --config .periphery.yml

Periphery integrates into CI via .github/workflows/periphery.yml, running on each pull request to prevent unused code accumulation.

GitHub Actions: Continuous Integration Orchestration

GitHub Actions coordinates the complete build pipeline. The .github/workflows directory contains workflow definitions that automate validation on every push and pull request.

Primary workflows:

Workflow file Responsibility
swift-tests.yml Builds the package and runs unit tests
periphery.yml Executes dead-code analysis
fetch_georelays.yml Updates relay metadata (operational task)

The swift-tests.yml workflow typically:

  1. Checks out source code
  2. Selects Xcode version matching project requirements
  3. Resolves SPM dependencies
  4. Builds targets with swift build or xcodebuild
  5. Executes test suite with swift test or xcodebuild test
  6. Archives build artifacts on failure for debugging

Build Tool Configuration Summary

Tool Config File Primary Function
Swift Package Manager Package.swift Dependency resolution and compilation
Xcode bitchat.xcodeproj/project.pbxproj Native app bundling and signing
Just Justfile Developer task automation
SwiftLint .swiftlint.yml Style enforcement
Periphery .periphery.yml Dead code detection
Xcode Config Configs/*.xcconfig Build-time constants

Summary

  • Swift Package Manager in Package.swift manages dependencies and provides cross-platform compilation via swift build.
  • Xcode and xcodebuild create signed .app bundles for iOS/macOS distribution, configured through bitchat.xcodeproj and .xcconfig files.
  • Just automates repetitive commands through recipes defined in Justfile.
  • SwiftLint enforces style rules from .swiftlint.yml, catching issues before merge.
  • Periphery scans for unused code using .periphery.yml, maintaining codebase health.
  • GitHub Actions workflows in .github/workflows/ orchestrate CI validation across all tools.

Frequently Asked Questions

Can Bitchat be built without Xcode?

Yes. The Swift Package Manager enables command-line compilation with swift build and testing with swift test. However, producing a signed iOS/macOS application bundle requires Xcode or xcodebuild for code signing, entitlements, and app packaging.

How do I run the same checks that CI performs?

Execute the core validation steps locally: swift build to compile, swift test to run tests, swiftlint lint for style checking, and periphery scan for dead-code detection. The Justfile likely provides a combined task for convenience.

What is the purpose of the .xcconfig files?

The Configs/Debug.xcconfig, Release.xcconfig, and Local.xcconfig files store build-time constants that vary by environment. This pattern keeps API endpoints, feature flags, and secrets out of source code while allowing Xcode to inject them during compilation.

Is SwiftLint required for contributions?

Yes. The swift-tests.yml workflow runs SwiftLint in CI and will fail builds that violate configured rules. Run swiftlint lint --config .swiftlint.yml before committing, or use swiftlint --fix to auto-correct eligible violations.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →