MrTechKing

5 min read

bitchat: Chat Without Internet Over a Bluetooth Mesh (GitHub, Scanned)

A free chat app that works with no internet or phone signal, hopping messages phone to phone over Bluetooth. No account needed.

bitchat logo
✅
Scan: safe. Nothing malicious. Know its privacy limits: the project's own whitepaper says nearby radios can follow a device, and it ships a prebuilt Tor library you have to trust or rebuild. Scanned Nov 10, 2026; the full report is below.

bitchat is a messaging app that keeps working when the internet does not. Phones running it find each other over Bluetooth Low Energy and pass messages along, up to seven hops, so a message can reach someone out of direct range through the phones in between. The README names protests, disasters and remote areas as uses, and it suits any crowded place where the network gives up. There are no accounts, no phone numbers and no central servers.

When you are online it can also use Nostr, an open network of public relays, for location-based channels at block, neighbourhood, city or country level, and for private messages when Bluetooth is out of reach. Private messages are end-to-end encrypted, with the Noise Protocol on the mesh. It has IRC-style commands such as /msg, /who and /slap, and a triple-tap wipes all data instantly.

bitchat is released into the public domain under the Unlicense. This repository holds the iPhone and Mac app and has about 37,000 stars and 59 contributors since July 2025; version 1.8.0 came out on 23 October 2026. An Android version is on the Play Store.

Who it is for

Groups at events, protests, campsites or anywhere the network is overloaded, people preparing for outages and emergencies, and anyone curious about chatting without an account or a company in the middle.

Getting started

1. Get it on iPhone, iPad or Mac from the App Store

https://apps.apple.com/us/app/bitchat-mesh/id6748219622

2. Or on Android from the Play Store

https://play.google.com/store/apps/details?id=com.bitchat.droid

3. Optional: check a build against the source yourself

https://github.com/permissionlesstech/bitchat/blob/main/docs/VERIFYING-A-BUILD.md

The README asks you to install only from the App Store or a build you verified, because the repository has faced takedown demands and unofficial mirrors cannot be checked. Our scan covers this repository's source, not the store apps.

Safety scan

We cloned permissionlesstech/bitchat at commit 04995f6 on Nov 10, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.

  • No secret hits and no pattern hits across 670 files and about 171,000 lines, mostly Swift. No install hooks.
  • The 3 committed binaries are prebuilt copies of one static library, libarti_bitchat.a, for macOS, iOS and the iOS simulator, about 7 to 15 MB each. It is Arti, the Tor project's Rust implementation, which bitchat uses to send Nostr traffic over Tor where enabled. The build script, localPackages/Arti/build-ios.sh, is in the repo, so you can rebuild it instead of trusting the copies.
  • 26 advisories, all in that Arti library's Cargo.lock: 1 high (a crash on a malformed certificate revocation list in rustls-webpki), 7 moderate, 7 low and 11 unrated, mostly unmaintained crates and TLS library issues.
  • Read the privacy limits. The whitepaper is unusually frank: the sender ID in every packet comes from a key that never changes, announcements carry nicknames and keys in clear text, so a passive listener nearby can list participants and follow a device from place to place. Messages are encrypted; who is around is not hidden. Location channels share an approximate area through public Nostr relays.
  • There is a /pay command for sending a Cashu ecash token you already hold, and pasted Lightning or Cashu payment links show as tappable chips. bitchat has no coin, wallet or token of its own, and its code comments warn against posting ecash in public channels.
  • 6 workflows. The scanner flagged one for pull_request_target, but the file only mentions it in a comment saying the job deliberately does not use it; it runs on pull_request with read-only permissions. No third-party actions. A security policy and licence are present.

What the scanner counted

CheckResult
SecretsNone found.
Suspicious codeNone found.
Install-time codeNone: nothing runs at install beyond the package manager itself.
Committed binaries3 executable or compiled objects committed; listed under the raw findings.
CI workflows6 workflows. 1 uses pull_request_target, none check out the pull request head. No third-party actions.
Network hosts15 distinct hosts referenced from source; most often unlicense.org, mint.example.com, raw.githubusercontent.com, www.noiseprotocol.org. No URLs to bare IP addresses.
Known vulnerabilities26 advisories across 465 pinned packages: 0 critical, 1 high, 7 moderate, 7 low, 11 unrated. localPackages/Arti/Cargo.lock: 465 packages, 26 advisories.
Project hygieneHas security policy, licence file. Missing automated dependency updates, CodeQL, contributing guide.
OpenSSF ScorecardNot scored: the project is not in Scorecard's weekly index.

The raw findings

Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.

Committed binaries (3)
  • localPackages/Arti/Frameworks/arti.xcframework/macos-arm64_x86_64/libarti_bitchat.a: Mach-O, 15 MB
  • localPackages/Arti/Frameworks/arti.xcframework/ios-arm64_x86_64-simulator/libarti_bitchat.a: Mach-O, 14 MB
  • localPackages/Arti/Frameworks/arti.xcframework/ios-arm64/libarti_bitchat.a: .a, 7 MB
Worst known vulnerabilities (24 of 26)
AdvisorySeverityPackageSummary
GHSA-82j2-j2ch-gfr8highrustls-webpki@0.103.8rustls-webpki: Denial of service via panic on malformed CRL BIT STRING
GHSA-434x-w66g-qw3rmoderatebytes@1.11.0bytes has integer overflow in BytesMut::reserve
GHSA-4grx-2x9w-596cmoderatersa@0.9.10Marvin Attack: potential key recovery through timing sidechannels
GHSA-2mjx-qc3c-rqvcmoderaterustls@0.23.36Rustls: TLS 1.3 handshake messages incorrectly accepted across encryption level boundaries
GHSA-c8m5-c952-6cm4moderaterustls@0.23.36Rustls: Session Debug formatting exposes TLS master secrets and resumption PSKs
GHSA-pwjx-qhcg-rvj4moderaterustls-webpki@0.103.8webpki: CRLs not considered authoritative by Distribution Point due to faulty matching logic
GHSA-7gcf-g7xr-8hxjmoderateserde_with@3.16.1serde_with: KeyValueMap serialization panics on empty sequence or map entries
GHSA-r6v5-fh4h-64xcmoderatetime@0.3.45time vulnerable to stack exhaustion Denial of Service attack
GHSA-3288-p39f-rqpvlowkeccak@0.1.5Unsoundness in opt-in ARMv8 assembly backend for `keccak`
GHSA-cq8v-f236-94qclowrand@0.8.5Rand is unsound with a custom logger using rand::rng()
GHSA-cq8v-f236-94qclowrand@0.9.2Rand is unsound with a custom logger using rand::rng()
GHSA-h2v8-394m-p7vvlowrustls@0.23.36Rustls: Brotli certificate decompression can allocate an attacker-controlled amount of memory up to 1 GiB before authent…
GHSA-w44r-93j7-qv28lowrustls@0.23.36rustls: An unauthenticated ServerHello poisons the per-name key-exchange record, so later ClientHellos carry only a clas…
GHSA-965h-392x-2mh5lowrustls-webpki@0.103.8webpki: Name constraints for URI names were incorrectly accepted
GHSA-xgp8-3hg3-c2mhlowrustls-webpki@0.103.8webpki: Name constraints were accepted for certificates asserting a wildcard name
RUSTSEC-2025-0141unknownbincode@2.0.1Bincode is unmaintained
RUSTSEC-2026-0204unknowncrossbeam-epoch@0.9.18Invalid pointer dereference in `fmt::Pointer` impl for `Atomic` and `Shared` when the underlying pointer is invalid
RUSTSEC-2026-0387unknowncrypto-bigint@0.5.5Multiple timing variability issues in operations intended to be constant-time
RUSTSEC-2026-0221unknownevent-listener@5.4.1`event-listener` allows `!Send` tags to cross thread boundaries via `StackSlot`
GHSA-72w2-rjgg-q729unknownlibsqlite3-sys@0.35.0`libsqlite3-sys` via C SQLite CVE-2026-119375
RUSTSEC-2026-0186unknownmemmap2@0.9.9Unchecked pointer offset in crate `memmap2`
RUSTSEC-2024-0436unknownpaste@1.0.15paste - no longer maintained
RUSTSEC-2026-0441unknownpin-utils@0.1.0`pin-utils` is unmaintained
RUSTSEC-2026-0173unknownproc-macro-error2@2.0.1proc-macro-error2 is unmaintained
Workflows worth a look

By the numbers

Stars37.1K
Forks5,889
Contributors59
Commits1,088
Open issues48
Open pull requests127
Releases21
Latest releasev1.8.0
LicenceUnlicense
Main languageSwift
Project age1 year
Last pushNov 8, 2026
Tracked files670
Lines of code170.8K
Checkout size47 MB

Lines by language: Swift 163.9K, Markdown 2,742, JSON 991, YAML 926, Shell 682, Python 611.

Questions

Is bitchat free?

Yes. The app is free on the App Store and Play Store, there is no account, and the code is in the public domain under the Unlicense.

How far can a bitchat message travel without internet?

Bluetooth reaches a short distance on its own, but each phone running bitchat relays messages, up to seven hops. In a crowd, a message can travel well beyond your own phone's range. With no other phones nearby, it only reaches people in direct range.

Is bitchat anonymous?

Not fully, and the project says so. Message contents are encrypted, but a nearby device can see who is broadcasting and track a phone between places because its ID does not rotate. Do not rely on it to hide that you are there.

Does bitchat need internet at all?

No for the Bluetooth mesh, which works fully offline with nearby phones. Location channels and private messages to people out of Bluetooth range use the internet through Nostr relays.


This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.