# How to Run Bitchat Locally: Complete Setup for macOS and iOS Development

> Learn how to run Bitchat locally on macOS and iOS. Follow our complete setup guide using Xcode or the just command runner for seamless decentralized messenger development.

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

---

**Build and run the Bitchat decentralized messenger locally using either Xcode or the `just` command runner, both targeting the `bitchat (macOS)` scheme with Swift 5.9+ and optional code-signing bypass.**

[Bitchat](https://github.com/permissionlesstech/bitchat) is an open-source, peer-to-peer messenger that combines **Bluetooth Mesh** for offline local communication and the **Nostr Protocol** for internet-based global reach. Running Bitchat locally lets you explore its dual-transport architecture, test mesh networking features, and contribute to the codebase. This guide covers two verified build methods using the repository's `bitchat.xcodeproj` and `Justfile`.

## Prerequisites for Running Bitchat Locally

Before building, ensure your environment meets these requirements:

- **Swift 5.9+** and **Xcode 15 or later**
- **macOS** for running the macOS target directly, or an iOS Simulator/Device for mobile testing
- **Homebrew** (for installing `just`)

The project uses standard Apple toolchains with no external dependencies beyond the Swift Package Manager packages already configured in `bitchat.xcodeproj`.

## Method 1: Build Bitchat Locally with Xcode

The repository ships with `bitchat.xcodeproj` containing preconfigured schemes for macOS and iOS builds.

### Step 1: Open the Project

```bash
open bitchat.xcodeproj

```

### Step 2: Configure Local Build Settings (Optional)

If you have an Apple Developer account, copy the example configuration to specify your team ID:

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

```

The `Local.xcconfig` file derives the **app-group identifier** from your team ID automatically. No manual entitlements editing is required.

### Step 3: Build Without Code Signing

To run locally without a paid developer account, use `CODE_SIGNING_ALLOWED=NO`:

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

```

The executable appears in the build products directory and can be launched directly.

### Step 4: Run iOS Simulator Tests (Optional)

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

```

Adjust `name=iPhone 17` to match your installed simulator devices.

## Method 2: Build Bitchat Locally with `just`

The repository includes a `Justfile` that streamlines common development tasks. This keeps build artifacts in `.DerivedData/` rather than polluting your working directory.

### Install `just`

```bash
brew install just

```

### Available `just` Commands for Local Development

| Command | Action |
|---------|--------|
| `just check` | Run static analysis and linting |
| `just run` | Build and launch the macOS app via `bitchat (macOS)` scheme |
| `just test` | Execute the SwiftPM test suite |
| `just test-ios` | Run iOS simulator tests (uses iPhone 17 by default) |
| `just clean` | Remove `.DerivedData/` and `.build/` directories |

### Quick Start: Build and Run

```bash
just run

```

This single command performs the same build as the Xcode method but with cleaner directory management.

## Understanding the Dual-Transport Architecture

When running Bitchat locally, the app automatically selects its transport layer based on availability:

```swift
// Transport selection logic from the Bitchat source
if mesh.isAvailable {
    transport = .bluetooth      // Local Bluetooth Mesh
} else if nostr.isConnected {
    transport = .nostr          // Internet Nostr relays
} else {
    transport = .queued         // Buffer until transport available
}

```

**Bluetooth Mesh** operates completely offline using multi-hop BLE with **Noise Protocol encryption**. **Nostr** provides global reach through geographic "location channels" based on geohash identifiers. The app seamlessly falls back from mesh to Nostr when peers move out of range.

## Key Files for Local Development

| File | Purpose |
|------|---------|
| `bitchat.xcodeproj` | Xcode project with macOS and iOS schemes |
| `Justfile` | Task definitions for `just check`, `just run`, `just test` |
| `Configs/Local.xcconfig.example` | Template for team ID and app-group configuration |
| [`README.md`](https://github.com/permissionlesstech/bitchat/blob/main/README.md) | Full architectural documentation |
| [`WHITEPAPER.md`](https://github.com/permissionlesstech/bitchat/blob/main/WHITEPAPER.md) | Deep dive into identity, encryption, and mesh protocols |
| `bitchat/` | Swift source implementing mesh, Nostr client, routing, and UI |

## Summary

- **Two build paths**: Use `xcodebuild` directly or the `just` task runner—both target `bitchat (macOS)`
- **No signing required**: `CODE_SIGNING_ALLOWED=NO` enables local development without a developer account
- **Configurable**: `Local.xcconfig` handles team-specific settings automatically
- **Clean builds**: `just` isolates build artifacts in `.DerivedData/`
- **Test coverage**: Run SwiftPM tests or iOS simulator tests with single commands

## Frequently Asked Questions

### Can I run Bitchat locally without an Apple Developer account?

Yes. Use `CODE_SIGNING_ALLOWED=NO` with `xcodebuild` or simply run `just run`. Both methods produce a functional macOS build without code signing. The repository's `Justfile` explicitly configures this for the default `just run` task.

### What is the difference between `just run` and building in Xcode?

Both compile the same `bitchat (macOS)` scheme. `just run` uses `xcodebuild` under the hood but routes `DerivedData` to `.DerivedData/` (git-ignored), keeping your repository clean. Xcode's GUI offers debugging tools; `just` offers faster iteration from the terminal.

### Does Bitchat require internet connectivity to run locally?

No. The **Bluetooth Mesh** transport functions entirely offline. You can test local peer discovery and messaging without network access. The **Nostr** transport only activates when internet connectivity is available and Bluetooth peers are unreachable.

### Which Swift version is required to build Bitchat locally?

**Swift 5.9 or later** is required, bundled with **Xcode 15+**. The project uses modern Swift concurrency features and SwiftPM package dependencies that depend on this baseline.