# How to Build the BitChat Project from Source: Complete Guide for macOS and iOS

> Build BitChat from source on macOS and iOS with our complete guide. Learn to use Xcode or the just command-line tool to compile the permissionlesstech/bitchat project.

- Repository: [permissionlesstech/bitchat](https://github.com/permissionlesstech/bitchat)
- Tags: how-to-guide
- Published: 2026-08-01

---

**You can build BitChat from source using either Xcode directly or the `just` command-line task runner, with both methods requiring a local configuration file (`Configs/Local.xcconfig`) that sets your Apple Developer Team ID.**

BitChat is a decentralized peer-to-peer messenger built in Swift that implements a **dual transport architecture**—combining Bluetooth mesh networking for offline communication with the Nostr protocol for internet-based messaging. This guide walks through building the permissionlesstech/bitchat repository from source on macOS, including setup, compilation, and verification steps.

## Prerequisites

Before building BitChat, ensure you have the following installed:

- **macOS** with Xcode 15 or later
- **Command Line Tools** (`xcode-select --install`)
- Either **Xcode GUI** or **just** command runner (`brew install just`)
- A valid **Apple Developer Team ID** (free or paid) for code signing configuration

The project uses Swift Package Manager for dependencies and targets both macOS and iOS platforms.

## Understanding the Build System

BitChat uses a hybrid build system centered on Xcode with optional `just` automation. The key files are:

- `bitchat.xcodeproj/` — Main Xcode project with schemes for macOS and iOS
- `Justfile` — Task definitions for `just build`, `just run`, `just test`
- `Configs/Local.xcconfig.example` — Template for local developer settings

The `just` tasks delegate to underlying `xcodebuild` commands, keeping artifacts in `.DerivedData/` (which is gitignored).

## Step 1: Configure Local Development Settings

BitChat requires a local configuration file to derive app and group identifiers from your Apple Developer Team ID. Without this step, code signing will fail.

```bash

# Clone the repository

git clone https://github.com/permissionlesstech/bitchat.git
cd bitchat

# Copy the example configuration

cp Configs/Local.xcconfig.example Configs/Local.xcconfig

```

Edit `Configs/Local.xcconfig` and replace `YOUR_TEAM_ID_HERE` with your actual Apple Developer Team ID (found at developer.apple.com/account > Membership). The configuration generates unique app and group container identifiers based on this value.

## Step 2: Build with Xcode (Recommended for First-Time Users)

The simplest approach uses the Xcode GUI or command-line tools directly. This method provides immediate feedback on build errors and integrates with debugger workflows.

### GUI Method

```bash

# Open the project in Xcode

open bitchat.xcodeproj

```

Select the **"bitchat (macOS)"** scheme, choose My Mac as destination, and press `Cmd+B` to build. For a quick debug build without code signing, disable "Sign to Run Locally" in the target's Signing & Capabilities tab.

### Command-Line Method

```bash

# Build debug binary without code signing

xcodebuild -project bitchat.xcodeproj \
  -scheme "bitchat (macOS)" \
  -configuration Debug \
  CODE_SIGNING_ALLOWED=NO \
  build

```

This produces an unsigned `.app` bundle in `build/Debug/`. Code signing is disabled (`CODE_SIGNING_ALLOWED=NO`) for rapid iteration; local Bluetooth functionality requires entitlements that normally need signing.

## Step 3: Build with `just` (Recommended for Automation)

For reproducible builds and CI/CD pipelines, use the `just` task runner defined in `Justfile`.

```bash

# Install just if not present

brew install just

# Verify repository state (linting, format checks)

just check

# Build macOS target

just build

# Run the built application

just run

```

The `just build` task invokes `xcodebuild` with the macOS scheme and routes output to `.DerivedData/`. Key `just` commands include:

| Command | Action |
|---------|--------|
| `just check` | Validate codebase state |
| `just build` | Compile macOS debug build |
| `just run` | Build and launch |
| `just test` | Run SwiftPM unit tests |
| `just test-ios` | Run iOS simulator tests |
| `just clean` | Remove build artifacts |

## Step 4: Run the Test Suite

BitChat includes comprehensive unit tests covering the Noise protocol implementation, mesh networking logic, and Nostr event handling.

```bash

# Run all Swift Package Manager tests

swift test

# Equivalent via just

just test

# iOS simulator tests (requires Xcode)

just test-ios

```

The test suite validates cryptographic operations including **XChaCha20-Poly1305** encryption for Nostr envelopes (kind-1059 events) and the **Noise XX handshake** used in Bluetooth mesh connections.

## Build Verification and Security

For production deployments, verify your build against published release hashes. The repository includes detailed instructions in [`docs/VERIFYING-A-BUILD.md`](https://github.com/permissionlesstech/bitchat/blob/main/docs/VERIFYING-A-BUILD.md).

```bash

# Example: compute SHA256 of built binary

shasum -a 256 .DerivedData/Build/Products/Debug/bitchat.app/Contents/MacOS/bitchat

```

Compare this against official release checksums published in GitHub releases. The [`scripts/validate_georelays.py`](https://github.com/permissionlesstech/bitchat/blob/main/scripts/validate_georelays.py) utility can additionally verify Nostr relay discovery logic used in the geohash-based channel system.

## Troubleshooting Common Build Issues

### Code Signing Failures

If you encounter "No signing certificate" errors:

1. Confirm `Configs/Local.xcconfig` exists and contains a valid `APP_TEAM_ID`
2. Check that your Apple ID has accepted all legal agreements at developer.apple.com
3. For local debugging, use `CODE_SIGNING_ALLOWED=NO` (Bluetooth features will be limited)

### Bluetooth Entitlement Restrictions

The Bluetooth mesh functionality requires the `com.apple.developer.bluetooth-peripheral` entitlement. Unsigned builds cannot advertise Bluetooth services on macOS. For full functionality, configure valid signing with your Team ID.

### Derived Data Conflicts

If builds behave unexpectedly:

```bash

# Clean and rebuild

just clean
rm -rf .DerivedData/
xcodebuild -project bitchat.xcodeproj -scheme "bitchat (macOS)" clean

```

## Summary

- **Two build paths**: Xcode GUI/command-line (`xcodebuild`) or automation via `just` task runner
- **Required configuration**: Copy and edit `Configs/Local.xcconfig` with your Apple Developer Team ID
- **Debug without signing**: Use `CODE_SIGNING_ALLOWED=NO` for rapid iteration (limited Bluetooth)
- **Testing**: `swift test` or `just test` for unit tests; `just test-ios` for simulator
- **Verification**: Compare build hashes against [`docs/VERIFYING-A-BUILD.md`](https://github.com/permissionlesstech/bitchat/blob/main/docs/VERIFYING-A-BUILD.md) guidelines

The dual transport architecture—Bluetooth mesh for offline, Nostr for online—requires specific entitlements that make proper code signing essential for full functionality.

## Frequently Asked Questions

### What is the minimum macOS version required to build BitChat?

BitChat targets macOS 14 (Sonoma) and iOS 17 as minimum deployment versions, though building requires Xcode 15 or later running on macOS 13.5+. Check [`Package.swift`](https://github.com/permissionlesstech/bitchat/blob/main/Package.swift) and the Xcode project settings for the exact platform specifications.

### Can I build BitChat without an Apple Developer account?

Yes, for limited local testing. Use `CODE_SIGNING_ALLOWED=NO` with `xcodebuild` or configure a free personal team in `Configs/Local.xcconfig`. However, **Bluetooth mesh functionality requires proper entitlements** that only function with valid code signing, so the offline messaging feature will not work in unsigned builds.

### Why does BitChat use `just` instead of Make or other build tools?

The `just` command runner provides a modern, shell-agnostic alternative to Make with clearer syntax and better cross-platform support. The `Justfile` in permissionlesstech/bitchat wraps `xcodebuild` calls with consistent flags and output directories, making builds reproducible across developer machines and CI environments.

### How do I verify my build matches an official release?

Follow the process documented in [`docs/VERIFYING-A-BUILD.md`](https://github.com/permissionlesstech/bitchat/blob/main/docs/VERIFYING-A-BUILD.md). Compute SHA256 hashes of your compiled binary and compare against published release checksums. The build process embeds version metadata and commit hashes that can be inspected with `strings bitchat.app/Contents/MacOS/bitchat | grep -i version`.