React Native Bluetooth Low Energy (BLE) mesh networking library with end-to-end encryption, offline messaging, peer-to-peer communication, and Noise Protocol security for iOS and Android
npm install react-native-ble-mesh




---
Imagine you're at a concert, camping trip, or during a power outage - no WiFi, no cell service. How do you text your friends?
This library lets phones talk to each other using Bluetooth! Messages hop from phone to phone until they reach your friend - even if they're far away.
```
You Friend's Your
Phone ----Bluetooth---> Friend's ----Bluetooth---> Friend
Phone (300m away!)
Think of it like a game of telephone, but for text messages!
---
`javascript
import { MeshNetwork } from 'react-native-ble-mesh';
// 1. Create your mesh network
const mesh = new MeshNetwork({ nickname: 'Alex' });
// 2. Start it up!
await mesh.start();
// 3. Send a message to everyone nearby
await mesh.broadcast('Hello everyone! š');
// 4. Listen for messages
mesh.on('messageReceived', (msg) => {
console.log(${msg.from} says: ${msg.text});`
});
That's it! Four lines of code and you're chatting without internet!
---
| Problem | Our Solution |
|---------|--------------|
| No WiFi or cell service | Works with just Bluetooth! |
| Friend is too far away | Messages hop through other phones |
| Worried about privacy? | All messages are encrypted |
| Phone battery dying? | Smart power saving built-in |
| Need to delete everything fast? | One-tap emergency wipe |
---
or #concert-squad. Only people who join can see the messages!---
Installation
$3
`bash
npm install react-native-ble-mesh react-native-ble-plx react-native-get-random-values
`$3
`bash
cd ios && pod install && cd ..
`Add these lines to your
ios/YourApp/Info.plist:`xml
NSBluetoothAlwaysUsageDescription
Chat with nearby friends using Bluetooth
NSBluetoothPeripheralUsageDescription
Chat with nearby friends using Bluetooth
UIBackgroundModes
bluetooth-central
bluetooth-peripheral
`$3
Add these lines to
android/app/src/main/AndroidManifest.xml:`xml
`$3
`javascript
// This MUST be the very first line in index.js or App.js
import 'react-native-get-random-values';// Now add your other imports
import { AppRegistry } from 'react-native';
// ...
`---
Quick Start Examples
$3
`javascript
import { MeshNetwork } from 'react-native-ble-mesh';// Create and start
const mesh = new MeshNetwork({ nickname: 'YourName' });
await mesh.start();
// Send message to everyone
await mesh.broadcast('Hi everyone!');
// Send private message to one person
await mesh.sendDirect('friend-id-here', 'Hey, just for you!');
// Receive messages
mesh.on('messageReceived', ({ from, text }) => {
console.log(
${from}: ${text});
});// When done
await mesh.stop();
`$3
`javascript
// Join a channel (like a chat room)
await mesh.joinChannel('#road-trip');// Send message to everyone in the channel
await mesh.sendToChannel('#road-trip', 'Are we there yet?');
// Leave when done
await mesh.leaveChannel('#road-trip');
`$3
`javascript
const mesh = new MeshNetwork({
nickname: 'PowerSaver',
batteryMode: 'low', // Uses less battery
});// Or let it decide automatically based on battery level
const mesh = new MeshNetwork({
nickname: 'Smart',
batteryMode: 'auto', // Adjusts automatically!
});
`$3
`javascript
// Enable panic mode
mesh.enablePanicMode({
trigger: 'triple_tap', // Triple tap to wipe
});// Or wipe everything immediately
await mesh.wipeAllData();
// All messages, keys, and data = GONE! šØ
`$3
`javascript
const health = mesh.getNetworkHealth();console.log(
Connected to ${health.activeNodes} people);
console.log(Network status: ${health.overallHealth}); // 'good', 'fair', or 'poor'
`---
Using React Hooks
If you're using React, we have easy hooks!
`javascript
import React, { useEffect } from 'react';
import { View, Text, Button } from 'react-native';
import { useMesh, useMessages, usePeers } from 'react-native-ble-mesh/hooks';
import { BLETransport } from 'react-native-ble-mesh';function ChatScreen() {
// Manage mesh lifecycle
const { mesh, state, initialize, destroy } = useMesh({ displayName: 'Alex' });
// Message handling (pass mesh instance)
const { messages, sendBroadcast } = useMessages(mesh);
// Peer tracking (pass mesh instance)
const { peers, connectedCount } = usePeers(mesh);
// Start mesh on mount
useEffect(() => {
const transport = new BLETransport();
initialize(transport);
return () => destroy();
}, []);
if (state !== 'active') return Starting mesh... ;
return (
Connected to {connectedCount} people
{messages.map(msg => (
{msg.senderId}: {msg.content}
))}
`> Note: The hooks (
useMesh, useMessages, usePeers) work with the lower-level MeshService. For simpler usage, use the MeshNetwork class directly as shown in the Quick Start examples above.---
All The Things You Can Do
$3
| Method | What It Does |
|--------|--------------|
|
mesh.start() | Turn on the mesh network |
| mesh.stop() | Turn it off (can restart later) |
| mesh.destroy() | Completely shut down (can't restart) |$3
| Method | What It Does |
|--------|--------------|
|
mesh.broadcast('Hi!') | Send to everyone nearby |
| mesh.sendDirect(id, 'Hey') | Send private message to one person |
| mesh.sendToChannel('#fun', 'Yo') | Send to a group channel |$3
| Method | What It Does |
|--------|--------------|
|
mesh.joinChannel('#name') | Join a channel |
| mesh.leaveChannel('#name') | Leave a channel |
| mesh.getChannels() | See what channels you're in |$3
| Method | What It Does |
|--------|--------------|
|
mesh.getPeers() | See everyone nearby |
| mesh.blockPeer(id) | Block someone |
| mesh.unblockPeer(id) | Unblock someone |$3
| Method | What It Does |
|--------|--------------|
|
mesh.getIdentity() | Get your info |
| mesh.setNickname('New Name') | Change your display name |$3
| Method | What It Does |
|--------|--------------|
|
mesh.enablePanicMode() | Enable emergency wipe |
| mesh.wipeAllData() | Delete everything NOW |$3
| Method | What It Does |
|--------|--------------|
|
mesh.getStatus() | Get current status |
| mesh.getNetworkHealth() | Check how good the network is |
| mesh.getBatteryMode() | See current battery mode |
| mesh.setBatteryMode('low') | Change battery mode |---
Events (When Things Happen)
Listen for these events:
`javascript
// Network started/stopped
mesh.on('started', () => { });
mesh.on('stopped', () => { });// Someone sent a message (any type)
mesh.on('messageReceived', ({ from, text, timestamp, type }) => { });
// Private message received
mesh.on('directMessage', ({ from, text, timestamp }) => { });
// Channel message received
mesh.on('channelMessage', ({ channel, from, text, timestamp }) => { });
// Message was delivered successfully
mesh.on('messageDelivered', ({ messageId, peerId }) => { });
// Found a new person nearby
mesh.on('peerDiscovered', (peer) => { });
// Connected to someone
mesh.on('peerConnected', (peer) => { });
// Someone left
mesh.on('peerDisconnected', (peer) => { });
// Channel events
mesh.on('channelJoined', ({ channel }) => { });
mesh.on('channelLeft', ({ channel }) => { });
// Network quality changed
mesh.on('networkHealthChanged', (healthInfo) => { });
// Message cached for offline peer
mesh.on('messageCached', ({ peerId, text }) => { });
// Cached messages delivered when peer came online
mesh.on('cachedMessagesDelivered', ({ peerId, delivered }) => { });
// Data was wiped (panic mode)
mesh.on('dataWiped', (result) => { });
// Something went wrong
mesh.on('error', (error) => { });
`---
How Secure Is It?
Very secure! Here's what protects your messages:
| Feature | What It Means |
|---------|---------------|
| Noise Protocol | Military-grade handshake to verify who you're talking to |
| ChaCha20 Encryption | Your messages are scrambled so only the recipient can read them |
| Forward Secrecy | Even if someone steals your keys later, old messages stay secret |
| No Permanent IDs | You don't have a permanent identity that can be tracked |
---
Frequently Asked Questions
$3
With one hop: about 30 meters (100 feet). With 7 hops through other phones: up to 300+ meters!$3
No, Bluetooth must be on. But you don't need WiFi or cell service!$3
No! Private messages are encrypted. Only you and your friend have the keys.$3
The library supports 50+ connected peers at once.$3
It uses some battery (Bluetooth is on), but you can use "low power" mode to minimize drain.$3
On iOS, it works with some limitations. On Android, it works fully in the background.---
Use Cases
- Concerts & Festivals - Text friends when cell towers are overloaded
- Camping & Hiking - Stay connected in the wilderness
- Emergencies - Communicate during power outages or disasters
- Protests & Events - When networks are restricted
- Gaming - Local multiplayer without internet
- Schools - Classroom activities without WiFi
---
Project Structure
`
react-native-ble-mesh/
āāā src/
ā āāā index.js # Main entry point
ā āāā MeshNetwork.js # High-level API
ā āāā crypto/ # Encryption stuff
ā āāā mesh/ # Routing & networking
ā āāā transport/ # Bluetooth layer
ā āāā hooks/ # React hooks
āāā docs/ # Documentation
āāā __tests__/ # Tests
`---
More Documentation
- Full API Reference - Every method explained
- React Native Guide - Platform-specific setup
- Security Details - How encryption works
- Protocol Spec - Technical wire format
- AI/Agent Instructions - For AI assistants
---
Testing
`bash
Run all tests
npm testRun with coverage report
npm run test:coverage
`---
Contributing
We love contributions! Here's how:
1. Fork this repository
2. Create a branch:
git checkout -b my-feature
3. Make your changes
4. Run tests: npm test`---
Inspired by BitChat - the original decentralized mesh chat.
Built with:
- react-native-ble-plx - Bluetooth Low Energy
- Noise Protocol - Secure handshakes
---
MIT License - do whatever you want with it! See LICENSE for details.
---
- Issues: GitHub Issues
- Questions: Open a Discussion on GitHub
---
Made with ā¤ļø for a more connected (yet private) world
If this library helps you, give it a ā on GitHub!