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:
- Checks out source code
- Selects Xcode version matching project requirements
- Resolves SPM dependencies
- Builds targets with
swift buildorxcodebuild - Executes test suite with
swift testorxcodebuild test - 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.swiftmanages dependencies and provides cross-platform compilation viaswift build. - Xcode and xcodebuild create signed
.appbundles for iOS/macOS distribution, configured throughbitchat.xcodeprojand.xcconfigfiles. - 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →