react-native-ble-mesh
v1.1.1
Published
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
Maintainers
Keywords
Readme
react-native-ble-mesh
Send messages without the internet. Like magic! ✨
What is this?
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!
See It In Action
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!
Why Use This?
| 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 |
Cool Features
📡 Messages That Hop
Your message can jump through up to 7 phones to reach someone far away. If Alice can't reach Dave directly, the message goes: Alice → Bob → Carol → Dave!
🔒 Secret Messages
Private messages are scrambled (encrypted) so only your friend can read them. Even if someone else's phone passes along the message, they can't peek!
📬 Offline Delivery
Friend's phone turned off? No problem! Your message waits and delivers when they come back online.
🔋 Battery Friendly
Choose how much battery to use:
- High Power = Faster messages, more battery
- Balanced = Good speed, normal battery (default)
- Low Power = Slower messages, saves battery
🚨 Panic Button
Triple-tap to instantly delete all messages and data. Everything gone in less than 0.2 seconds!
💬 Group Channels
Create chat rooms like #camping-trip or #concert-squad. Only people who join can see the messages!
Installation
Step 1: Install the package
npm install react-native-ble-mesh react-native-ble-plx react-native-get-random-valuesStep 2: iOS Setup
cd ios && pod install && cd ..Add these lines to your ios/YourApp/Info.plist:
<key>NSBluetoothAlwaysUsageDescription</key>
<string>Chat with nearby friends using Bluetooth</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>Chat with nearby friends using Bluetooth</string>
<key>UIBackgroundModes</key>
<array>
<string>bluetooth-central</string>
<string>bluetooth-peripheral</string>
</array>Step 3: Android Setup
Add these lines to android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />Step 4: Add this to the TOP of your app
// 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
Example 1: Simple Chat
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();Example 2: Group Channels
// 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');Example 3: Save Battery
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!
});Example 4: Emergency Delete
// 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! 💨Example 5: Check Network Health
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!
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 <Text>Starting mesh...</Text>;
return (
<View>
<Text>Connected to {connectedCount} people</Text>
{messages.map(msg => (
<Text key={msg.id}>{msg.senderId}: {msg.content}</Text>
))}
<Button title="Say Hi!" onPress={() => sendBroadcast('Hello!')} />
</View>
);
}Note: The hooks (
useMesh,useMessages,usePeers) work with the lower-levelMeshService. For simpler usage, use theMeshNetworkclass directly as shown in the Quick Start examples above.
All The Things You Can Do
Starting & Stopping
| 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) |
Sending Messages
| 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 |
Channels (Group Chats)
| Method | What It Does |
|--------|--------------|
| mesh.joinChannel('#name') | Join a channel |
| mesh.leaveChannel('#name') | Leave a channel |
| mesh.getChannels() | See what channels you're in |
People Management
| Method | What It Does |
|--------|--------------|
| mesh.getPeers() | See everyone nearby |
| mesh.blockPeer(id) | Block someone |
| mesh.unblockPeer(id) | Unblock someone |
Your Identity
| Method | What It Does |
|--------|--------------|
| mesh.getIdentity() | Get your info |
| mesh.setNickname('New Name') | Change your display name |
Safety Features
| Method | What It Does |
|--------|--------------|
| mesh.enablePanicMode() | Enable emergency wipe |
| mesh.wipeAllData() | Delete everything NOW |
Network Info
| 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:
// 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
How far can messages travel?
With one hop: about 30 meters (100 feet). With 7 hops through other phones: up to 300+ meters!
Does it work if Bluetooth is off?
No, Bluetooth must be on. But you don't need WiFi or cell service!
Can someone read my private messages?
No! Private messages are encrypted. Only you and your friend have the keys.
How many people can be in the network?
The library supports 50+ connected peers at once.
Does it drain my battery?
It uses some battery (Bluetooth is on), but you can use "low power" mode to minimize drain.
Does it work in the background?
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__/ # TestsMore 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
# Run all tests
npm test
# Run with coverage report
npm run test:coverageContributing
We love contributions! Here's how:
- Fork this repository
- Create a branch:
git checkout -b my-feature - Make your changes
- Run tests:
npm test - Push and create a Pull Request
Credits
Inspired by BitChat - the original decentralized mesh chat.
Built with:
- react-native-ble-plx - Bluetooth Low Energy
- Noise Protocol - Secure handshakes
License
MIT License - do whatever you want with it! See LICENSE for details.
Get Help
- Issues: GitHub Issues
- Questions: Open a Discussion on GitHub
