Does BitChat Have a Server Architecture? Understanding Its Decentralized Design

BitChat does not use a traditional server architecture; instead, it employs a serverless design combining a local Bluetooth Low-Energy (BLE) mesh network with the public Nostr relay network, optionally routed through Tor.

BitChat's architecture represents a deliberate departure from conventional messaging apps that rely on centralized backend infrastructure. The permissionlesstech/bitchat repository implements a dual-transport system where routing, persistence, and message delivery happen across peer-to-peer connections and open-source Nostr relays rather than proprietary servers. This article examines how BitChat functions without a dedicated backend and what components assume server-like responsibilities.

Core Components of the BitChat Server Architecture

BitChat distributes traditional server functions across several client-side components. Each plays a distinct role in message routing, storage, and connectivity.

BLE Mesh Transport

The BLE mesh transport enables infrastructure-free local communication. Each BitChat device operates simultaneously as both a GATT central and peripheral, forwarding packets through a controlled flooding mechanism. This creates an ad-hoc network where messages propagate device-to-device without internet connectivity.

The implementation lives in docs/BLE-ARCHITECTURE-V3.md, which details the packet format and flood control mechanisms that prevent network congestion. Unlike traditional Bluetooth pairing, this mesh allows multi-hop message relay between devices that are not directly paired.

Nostr Relay Transport

When BLE connectivity is unavailable, BitChat bridges to the internet through public Nostr relays. The NostrRelayManager in bitchat/Nostr/NostrRelayManager.swift manages WebSocket connections to a configurable pool of relays, handling:

  • Connection lifecycle and reconnection with exponential backoff
  • Per-relay statistics and health monitoring
  • Tor integration for traffic anonymization
  • Built-in and user-added relay management

Messages travel as encrypted private envelopes that relays store temporarily without reading contents. This provides store-and-forward capability for peers that are offline or out of mesh range.

MessageRouter: The Traffic Controller

The MessageRouter in bitchat/Services/MessageRouter.swift serves as the central decision engine. It implements a priority-based routing strategy:

  1. Active BLE link — preferred for local, low-latency delivery
  2. Nostr relay path — fallback for internet-wide reachability
  3. Courier system — invoked when neither transport can deliver promptly

The send(_:completion:) API exposes this routing logic to higher-level components:

router.send(message) { result in
    switch result {
    case .success:  print("Delivered")
    case .failure(let err): print("Failed: \(err)")
    }
}

ConversationStore: State Management

ConversationStore functions as the single source of truth for all conversation state. It maintains:

  • Public channel timelines
  • Private conversation contexts
  • Transport-specific identifiers that map between BLE and Nostr addressing schemes

This component mirrors how a traditional server would manage session state, but operates entirely on-device with no external database dependency.

AppRuntime: Lifecycle and Service Composition

AppRuntime in ARCHITECTURE_V2.md acts as the composition root, initializing and wiring together:

  • BLE service startup
  • NostrRelayManager instantiation
  • Tor integration
  • Background task scheduling
  • Screenshot and reconnect observers

How Message Delivery Works Without Servers

BitChat's message flow demonstrates how serverless operation is achieved:

Startup Sequence

During initialization, AppRuntime creates the three core transport components. The ChatViewModelBootstrapper coordinates this boot process, ensuring MessageRouter has active connections before accepting user messages.

Transport Selection Logic

When MessageRouter.receiveSendRequest() is invoked, it evaluates:

  • Whether recipient is visible on the local BLE mesh
  • Nostr relay connectivity status
  • Message urgency and courier eligibility

This decision happens locally with no server consultation.

Store-and-Forward Fallbacks

For undeliverable messages, BitChat implements three mechanisms described in WHITEPAPER.md:

  • Sender Outbox — sealed messages persist locally until any transport succeeds
  • Couriers — encrypted envelopes delegated to physically proximate peers for delayed delivery
  • Nostr Mailboxes — 24-hour encrypted storage on public relays

These systems collectively replace server-side message queues.

Tor Integration for Anonymity

Optional Tor encapsulation, detailed in docs/TOR-INTEGRATION.md, routes Nostr traffic through the anonymity network. This occurs at the NostrRelayManager level without requiring separate Tor-enabled relay infrastructure.

Configuring Nostr Relay Connections

Users can extend BitChat's connectivity by adding custom Nostr relays. The NostrRelayManager supports this through its dependency system:

let dependencies = NostrRelayManagerDependencies.live()
let nostrManager = NostrRelayManager(dependencies: dependencies)

Adding a relay persists to UserDefaults and refreshes the active connection pool:

let customURL = "wss://my.custom.relay"
NostrRelaySettings.addCustomRelay(customURL)
nostrManager.reloadRelays()

The live() factory method in NostrRelayManagerDependencies (lines 84-85) consults NostrRelaySettings.customRelays() when building the relay list.

Key Architecture Files

File Purpose
docs/ARCHITECTURE_V2.md Runtime layer, store architecture, and feature-scoped model design
WHITEPAPER.md Complete protocol specification including dual-transport rationale
bitchat/Nostr/NostrRelayManager.swift WebSocket connection management and relay statistics
bitchat/Services/MessageRouter.swift Transport selection and courier invocation
bitchat/ViewModels/ChatViewModelBootstrapper.swift Runtime initialization and component wiring
docs/TOR-INTEGRATION.md Tor anonymization implementation
docs/BLE-ARCHITECTURE-V3.md Mesh networking protocol and packet structure

Design Rationale: Why No Dedicated Server?

BitChat's serverless architecture directly serves three project goals:

  • Decentralization — No single point of control or failure
  • Censorship resistance — Communication persists without permission from infrastructure operators
  • Offline resilience — BLE mesh functionality in environments without reliable internet

The "server" role is intentionally fragmented: Nostr relays provide public infrastructure storage, while peer devices handle routing, encryption, and local persistence. This eliminates operational costs for backend infrastructure while maximizing user autonomy.

Summary

  • BitChat has no dedicated server component; it uses a distributed dual-transport architecture instead
  • BLE mesh provides local, infrastructure-free routing through device-to-device forwarding
  • Nostr relays offer internet-wide message storage and delivery without proprietary infrastructure
  • MessageRouter coordinates transport selection and fallback mechanisms locally
  • AppRuntime composes services including optional Tor integration for Nostr traffic
  • All state management occurs in ConversationStore on the client device
  • Users can extend connectivity by adding custom Nostr relays through NostrRelaySettings

Frequently Asked Questions

Does BitChat require any server infrastructure to function?

No. BitChat can operate entirely through its BLE mesh transport without internet connectivity. When internet access is available, it uses public Nostr relays that anyone can run—no proprietary backend is required. The app stores messages locally and manages all routing decisions on-device.

How does BitChat handle messages when both sender and receiver are offline?

BitChat employs three store-and-forward mechanisms: the sender's local outbox persists messages until delivery succeeds; couriers (nearby peers) can carry encrypted envelopes; and Nostr relays store encrypted messages for up to 24 hours. These systems operate without centralized message queues.

What are Nostr relays and why does BitChat use them?

Nostr relays are open-source, public servers that store and forward encrypted event envelopes. BitChat uses them as a bridge between separate BLE meshes and for delivery when peers lack local connectivity. The NostrRelayManager handles connections, reconnection logic, and optional Tor routing—treating relays as interchangeable infrastructure rather than trusted authorities.

Can I run my own infrastructure to support BitChat?

Yes. While unnecessary for basic operation, you can operate a private Nostr relay and add it through NostrRelaySettings.addCustomRelay(). The relay must support standard Nostr protocol extensions for encrypted direct messages. This provides additional redundancy without centralizing control.

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 →