Some messaging tools try to be private while still depending on accounts, phone numbers, push infrastructure, and a central service.
Bitchat goes in a different direction: nearby devices can talk over Bluetooth mesh, and internet-backed reach comes through Nostr rather than a project-owned server.
That makes it interesting from a FOSS engineering point of view. It is not a Docker app to self-host.
It is a native Swift app that explores what local-first, peer-to-peer communication can look like on Apple devices.
Bitchat is a decentralized peer-to-peer messaging app with Bluetooth mesh for offline communication and Nostr protocol support for global reach.
- Bitchat GitHub repository
- Bitchat project site
- Bitchat on the App Store
- License: Unlicense / public domain ✅
What is Bitchat?
Bitchat is a native iOS and macOS messaging app for peer-to-peer chats without accounts, phone numbers, or a central BitChat server. The repository describes it as a dual-transport app: Bluetooth Low Energy mesh for local/offline messaging and Nostr for internet-based messaging and location channels.
The local mesh side is the part that stands out. Devices can discover nearby peers, relay packets across multiple hops, and keep communicating in places where normal internet access is unavailable or untrusted. The Nostr side expands the design beyond physical proximity, especially for private-message fallback and geohash-based location channels.
This is the kind of FOSS project that is useful to read even if you do not plan to use the app every day.
The codebase contains a real protocol stack, privacy trade-off documentation, CoreBluetooth engineering, Noise-based encryption, source-routing notes, and a serious test suite.
Why This Project is Interesting
- No account model: Bitchat does not ask for phone numbers, email addresses, or usernames tied to a hosted service.
- Offline-first transport: Bluetooth mesh gives the app a path for local communication when internet access is not available.
- Hybrid reach: Nostr fallback gives the project an internet transport without turning the project itself into the central service.
- Privacy posture is documented: The repo includes a privacy policy and a privacy assessment that discuss both mitigations and residual risks.
- Public domain license: The project uses the Unlicense, which makes reuse and experimentation straightforward.
Tech Overview of Bitchat
Bitchat is mostly Swift and targets iOS 16+ and macOS 13+. The root Package.swift uses Swift tools 5.9 and pulls in local packages for shared protocol types, logging, and Tor support.
The main components are:
bitchat/Services/BLE/for Bluetooth mesh transport and policy components.bitchat/Noise/for Noise protocol sessions and validation.bitchat/Nostr/for relay, identity, and embedded BitChat-over-Nostr behavior.localPackages/BitFoundationfor packet models and binary encoding.localPackages/BitLoggerfor secure logging and string sanitization.localPackages/Artifor the Tor integration scaffold.
The repository also includes 100+ Swift test files covering BLE behavior, fragmentation, Noise, Nostr helpers, geohash/location channels, command processing, message deduplication, and end-to-end mock mesh flows.
The Messaging Architecture
Bitchat is organized like a layered protocol stack:
- Application layer: chat messages, read receipts, delivery status, location channels, private/public conversation state.
- Session layer: packet framing, message type, timestamp, TTL, recipient, route, fragmentation, and binary encoding.
- Encryption layer: Noise sessions for private peer-to-peer messages and Nostr gift-wrapped fallback.
- Transport layer: Bluetooth LE mesh locally, Nostr relays over the internet.
The packet model is compact because BLE is constrained. BitchatPacket carries routing fields, payload data, optional signatures, TTL, and optional source-route data.
The source-routing docs describe a v2 packet format with a 4-byte payload length and route lists for intermediate hops.
That matters because naive mesh flooding gets expensive quickly. Source routes and neighbor gossip can reduce unnecessary rebroadcasting while keeping fallback behavior when a route is unavailable.
Bluetooth Mesh
The BLE side is handled by BLEService plus a set of smaller policy and state objects. The service acts as both a central and a peripheral, tracks peers, handles fragmentation, manages relays, emits transport events, and adapts scan/announce behavior.
Some implementation details worth noting:
- Debug and release builds use separate BLE service UUIDs.
- The app avoids publishing a BLE local name by default.
- Packets larger than the BLE MTU are fragmented and reassembled.
- TTL and relay policies limit message spread.
- Jitter and duty-cycle behavior reduce synchronized bursts.
- Dedicated components handle fanout, packet freshness, ingress links, outbound buffers, scan duty, route forwarding, and fragment planning.
That decomposition is a good sign. It lets the project test mesh policies without needing every test to depend on live radios.
Field Note: Bluetooth Range
In a quick Android-to-iOS Bluetooth test, I could walk roughly 80 steps before the connection dropped. Treat that as anecdotal rather than a guaranteed range: Bluetooth mesh performance depends heavily on device radios, obstacles, body position, background limits, and whether relay peers are nearby.
Nostr, Location Channels, and Tor
Bitchat also includes Nostr support. In the README, Nostr is used for global reach, location channels, and fallback private delivery when Bluetooth is unavailable.
Location channels are based on geohash precision. A short geohash represents a larger region; a longer geohash gets closer to a neighborhood or block-level channel. The app can use these channels for local community chat over internet relays rather than only immediate Bluetooth range.
The repo also includes a Tor integration scaffold. The documented intent is to route network traffic through a local Tor SOCKS5 proxy by default, with fail-closed behavior when Tor is not ready. For local development there is a bypass flag, but release-style behavior is meant to avoid silently falling back to clearnet.
Privacy Model
Bitchat’s privacy policy is unusually direct. It says the app does not collect names, emails, phone numbers, analytics, telemetry, or profiles. Mesh messages do not go through a project-owned server.
The privacy assessment is also useful because it does not pretend that every metadata problem disappears. BLE presence is still observable at the radio layer. Nostr relays can still see encrypted events passing through them. Timing correlation can be reduced, not magically removed.
The mitigations are practical:
- BLE announces are limited to nickname and Noise public key.
- No BLE local name is used by default.
- Private messages use end-to-end encryption.
- Nostr fallback is constrained to peers where key mapping exists.
- Read receipts and delivery acknowledgments are throttled.
- Logs are filtered through a secure logger.
- Emergency wipe clears keys, sessions, cached state, and disconnects transports.
Building Bitchat from Source
This is not a server deployment, so there is no Docker Compose file to run. The useful path is building the native app locally.
Pre-Requisites — Apple Build Environment
You need a macOS machine with Xcode installed. For device builds, you also need Apple signing configured. The repository targets iOS 16+ and macOS 13+.
The Justfile checks for full Xcode, not just command-line tools.
Build with Xcode
Clone the repo and open the project:
git clone https://github.com/permissionlesstech/bitchat.git
cd bitchat
open bitchat.xcodeproj
For device builds, create the local config file:
cp Configs/Local.xcconfig.example Configs/Local.xcconfig
Then add your Developer Team ID and update the app group entitlement values for your bundle ID. The README notes that this still needs manual entitlement work.
Build the macOS App with Just
The repo also includes a Justfile for macOS development:
brew install just
just check
just run
just run builds the macOS scheme and launches the app from Xcode DerivedData. When you are done, use:
just clean
That restores temporary project changes and removes local build artifacts.
What I Would Watch
Bitchat is ambitious, and the repo is active. I would pay attention to these areas before relying on it for sensitive situations:
- How the Tor-by-default scaffold behaves in production builds.
- How Nostr relay selection and relay metadata exposure evolve.
- How the source-routing protocol behaves under real-world BLE churn.
- Whether low-visibility mode or reduced scan aggressiveness becomes user-configurable.
- How Apple platform background limits affect real mesh availability.
None of these are dealbreakers. They are the normal hard edges of building real peer-to-peer mobile software.
Conclusion
Bitchat is a strong project to study if you care about local-first communication, decentralized protocols, and privacy-oriented mobile engineering. It combines Bluetooth mesh, Noise encryption, Nostr fallback, Tor integration work, and a native Swift app architecture in one public-domain codebase.
For FOSS readers, the most valuable part may be the architecture itself. The project shows how much work sits underneath a simple promise like “no accounts, no servers, no phone numbers.” Discovery, routing, encryption, identity, relay fallback, UI state, and privacy controls all need careful treatment.
If you are exploring privacy-first messaging, Bitchat is worth cloning and reading. Even if you never ship an Apple app, the protocol and transport design notes are useful.
FAQ
Is Bitchat self-hosted?
Does Bitchat require the internet?
Is the Docker section missing?
What cover image should this post use?
Use a local source PNG at assets/covers/bitchat-mesh-messaging.png and frontmatter path covers/bitchat-mesh-messaging.png.
Prompt:
Create a polished editorial technology cover for the post "Bitchat - Decentralized Mesh Messaging". Topic: a public-domain Swift app for private peer-to-peer messaging over Bluetooth mesh with Nostr fallback. Scene: several nearby phones and laptops forming a subtle encrypted mesh, with relay nodes fading into the background for global reach. Style: modern technical illustration with realistic materials, subtle depth, crisp lighting, professional open-source engineering tone. Composition: wide blog hero/social preview, clear focal point, generous safe margins. Palette: neutral base with deep green and steel blue accents, not monochrome. Constraints: no logos, no trademarks, no watermark, no fake badges, no readable code, no Socialify/GitHub card layout. Output: PNG source for assets/covers/bitchat-mesh-messaging.png.
Comments