# How to Run bitchat Locally for Development: A Complete Setup Guide

> Learn to run bitchat locally for development. Clone the repository, configure, and build on macOS or iOS simulator for seamless local testing.

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

---

**Clone the repository, copy the local config template, and build with Xcode or the `just` command runner to run bitchat on macOS or the iOS simulator.**

Setting up **bitchat** for local development requires configuring your Apple Developer credentials and choosing between Xcode's graphical interface or terminal-based workflows. This Swift-based dual-transport messenger combines Bluetooth mesh networking with Nostr protocol integration, and both build paths use the same underlying project structure at `bitchat.xcodeproj` and [`Package.swift`](https://github.com/permissionlesstech/bitchat/blob/main/Package.swift).

## Prerequisites and Initial Setup

Before building, ensure you have **Xcode 15+** and **Swift 5.9+** installed. The project also supports **just**—a command runner that wraps common build tasks.

### Install the Command Runner (Optional but Recommended)

```bash
brew install just

```

The `Justfile` at the repository root defines shortcuts like `just run` and `just test` that map directly to `xcodebuild` invocations.

### Configure Local Developer Settings

**bitchat** requires an Apple Developer Team ID for signed device builds. Copy the example configuration and edit it with your credentials:

```bash
cp Configs/Local.xcconfig.example Configs/Local.xcconfig

```

Open `Configs/Local.xcconfig` and replace `APP_TEAM_ID` with your actual Apple Developer team identifier. This file generates unique app-group identifiers referenced in `bitchat/bitchat.entitlements` and `bitchat/bitchat-macOS.entitlements` via the `$(APP_GROUP_ID)` variable.

## How to Build bitchat Locally: Two Methods

You can run **bitchat** locally using either **Xcode directly** or the **`just` command runner**. Both compile the same Swift package and produce identical outputs.

### Method 1: Building with Xcode

Open the project and select your target scheme:

```bash
open bitchat.xcodeproj

```

In Xcode:
- Choose **"bitchat (macOS)"** for local macOS runs
- Choose **"bitchat (iOS)"** for simulator testing
- Press **Cmd+R** to build and run

For unsigned macOS builds during early iteration, disable code signing in the build settings or use the terminal command below.

### Method 2: Building with `just` Commands

The `Justfile` provides concise shortcuts for common tasks:

| Command | Action | Equivalent `xcodebuild` |
|---------|--------|------------------------|
| `just run` | Build and run macOS (unsigned) | Debug build with `CODE_SIGNING_ALLOWED=NO` |
| `just test` | Run SwiftPM unit tests | `swift test` |
| `just test-ios` | Run iOS simulator tests | iPhone 17 simulator, Debug scheme |
| `just check` | Lint and verify before commit | Multiple validation steps |
| `just clean` | Remove derived data | `xcodebuild clean` |

Example workflow:

```bash

# Clone and enter repository

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

# Setup config (edit with your team ID)

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

# Quick macOS build and launch

just run

```

## Running bitchat Tests Locally

The test suite validates core logic before UI work. Execute tests at three levels:

### Swift Package Manager Tests

```bash
swift test

```

This runs the full test suite defined in [`Package.swift`](https://github.com/permissionlesstech/bitchat/blob/main/Package.swift), covering units in `bitchatTests/`.

### iOS Simulator Tests

```bash
just test-ios

```

By default, this targets the **iPhone 17** simulator. If unavailable, list alternatives:

```bash
xcodebuild -showdestinations -project bitchat.xcodeproj -scheme "bitchat (iOS)"

```

Then modify the destination in your command or `Justfile` invocation.

### Manual `xcodebuild` for iOS Testing

```bash
xcodebuild -project bitchat.xcodeproj \
  -scheme "bitchat (iOS)" \
  -sdk iphonesimulator \
  -destination 'platform=iOS Simulator,name=iPhone 17' \
  test

```

## Unsigned macOS Builds for Faster Iteration

During active development, skip code signing for quicker builds:

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

```

The `just run` command executes this exact configuration automatically.

## Key Source Files for Development

Understanding the project structure helps navigate local development:

- **`bitchat/Sync/`** — Core routing logic bridging Bluetooth mesh and Nostr protocols
- **`bitchat/Nostr/`** — Nostr relay integration and event handling
- **`bitchat/Noise/`** — Noise protocol encryption for Bluetooth mesh packets
- **[`Package.swift`](https://github.com/permissionlesstech/bitchat/blob/main/Package.swift)** — Swift package manifest with local dependencies (`BitLogger`, `BitFoundation`)
- **`Justfile`** — Build automation shortcuts (lines 47-53 define core targets)

The dual-transport architecture separates local mesh messaging (Bluetooth) from global reach (Nostr), with synchronization managed in the `Sync/` directory.

## Cleaning Build Artifacts

Remove derived data without affecting source:

```bash
just clean

```

Or manually:

```bash
xcodebuild -project bitchat.xcodeproj clean

```

This clears `.DerivedData/` and `.build/` directories while preserving your code changes.

## Summary

- **Copy `Configs/Local.xcconfig.example`** to `Configs/Local.xcconfig` and set your `APP_TEAM_ID` for device builds
- **Use `just run`** for quick unsigned macOS builds or **open `bitchat.xcodeproj`** in Xcode for graphical debugging
- **Run `swift test`** for package-level tests and **`just test-ios`** for simulator validation
- **Target `bitchat/Sync/` and `bitchat/Nostr/`** for transport-layer development

Both Xcode and `just` workflows compile identical outputs from the same [`Package.swift`](https://github.com/permissionlesstech/bitchat/blob/main/Package.swift) and project files, so choose based on your preference for GUI or terminal development.

## Frequently Asked Questions

### Do I need an Apple Developer account to run bitchat locally?

**No for macOS, yes for iOS devices.** Unsigned macOS builds work immediately with `CODE_SIGNING_ALLOWED=NO` or `just run`. However, deploying to physical iOS devices requires a valid Apple Developer Team ID in `Configs/Local.xcconfig`. Simulator testing does not require a paid developer account.

### What is the `just` command and why does bitchat use it?

**`just`** is a command runner similar to `make` but simpler. The `Justfile` in bitchat's root provides memorable shortcuts—`just run`, `just test`, `just clean`—that wrap lengthy `xcodebuild` invocations. According to the bitchat source, this reduces terminal typing and ensures consistent build flags across team members.

### How do I fix "iPhone 17 simulator not found" errors?

**List available simulators** with `xcodebuild -showdestinations -project bitchat.xcodeproj -scheme "bitchat (iOS)"`, then edit the destination name in your command. The README (lines 141-145) documents this fallback approach, or you can modify the `just test-ios` definition in the `Justfile` to reference an installed simulator like "iPhone 15" or "iPhone SE".

### Where is the core messaging logic located in the source?

**Transport and encryption code resides in three key directories:** `bitchat/Sync/` handles mesh-to-Nostr routing, `bitchat/Nostr/` manages relay connections, and `bitchat/Noise/` implements the Bluetooth encryption layer. These integrate in the main app target defined in `bitchat.xcodeproj`.