A serverless, peer-to-peer messaging application built with React Native
Chat without internet infrastructure โข No central servers โข True mesh networking
Meshage is a decentralized messaging application that enables direct device-to-device communication without requiring internet connectivity or central servers. Using Google Nearby Connections API, devices form a mesh network where messages are automatically routed through intermediate peers to reach their destination.
- ๐ True P2P Communication - Direct device-to-device messaging
- ๐ Mesh Network Routing - Messages hop through peers to reach distant devices
- ๐ Privacy-First - No data stored on external servers
- ๐ฌ Broadcast & Direct Messages - Public chat room and private conversations
- ๐ฅ Friend System - Add friends with persistent IDs across sessions
- ๐พ Persistent Chat History - Messages saved locally per conversation
- ๐ก Offline-First - Works without internet or cellular connection
- ๐ Auto-Discovery - Automatically finds nearby devices
- ๐จ Modern UI - Clean, dark-themed interface
- Frontend: React Native + TypeScript
- Navigation: React Navigation
- Storage: AsyncStorage (persistent local storage)
- Networking: Google Nearby Connections API (Android)
- State Management: React Hooks (custom hooks pattern)
meshage/
โโโ src/
โ โโโ screens/
โ โ โโโ OnboardingScreen.tsx # Username setup
โ โ โโโ BroadcastScreen.tsx # Broadcast chat screen
โ โ โโโ FriendsScreen.tsx
โ โ โโโ ChatListScreen.tsx
โ โ โโโ ChatDetailsScreen.tsx
โ โ โโโ SettingsScreen.tsx # App settings
โ โโโ components/
โ โ โโโ AddFriendBanner.tsx
โ โ โโโ ChatItem.tsx
โ โ โโโ Header.tsx
โ โ โโโ NearbyDeviceModal.tsx # App settings
โ โโโ types/
โ โ โโโ navigation.ts # TypeScript interfaces
โ โโโ android/
โ โโโ app/src/main/java/com/meshage/
โ โโโ MeshNetworkModule.kt # Native Android module
โโโ README.md
- Node.js (v18 or higher)
- React Native CLI installed globally
- Android Studio with Android SDK
- JDK 17 or higher
- Physical Android device (Nearby Connections requires real hardware)
Note: Mesh networking features require physical Android devices. Emulators cannot test P2P connectivity.
-
Clone the repository
git clone https://github.com/yourusername/meshage.git cd meshage -
Install dependencies
npm install # or yarn install -
Install Android dependencies
cd android ./gradlew clean cd ..
-
Start Metro bundler
npm start # or yarn start -
Build and run on Android
npm run android # or yarn android
The app requires the following Android permissions:
ACCESS_FINE_LOCATION- For Nearby Connections discoveryBLUETOOTH_ADVERTISE- For advertising device presenceBLUETOOTH_CONNECT- For connecting to peersBLUETOOTH_SCAN- For discovering nearby devicesNEARBY_WIFI_DEVICES- For WiFi Direct connections
When you open the app, your device:
- Broadcasts its presence with format:
"Username|PersistentID" - Scans for other nearby Meshage devices
- Automatically connects to discovered peers
Device A โโ Device B โโ Device C
โ โ
Device D Device E
Devices form a mesh where:
- Each device maintains multiple connections
- Messages are forwarded through intermediate peers
- Network self-heals when devices disconnect
Broadcast Messages:
User A sends "Hello World"
โ
Message format: "deviceID|||username|||Hello World"
โ
Forwarded to all connected peers
โ
Each peer forwards to their connections (except sender)
โ
Deduplication prevents message loops
Direct Messages (Friends):
User A โ Friend B (not directly connected)
โ
Message format: "DIRECT_MSG:friendID:message"
โ
Broadcast to mesh network
โ
Only Friend B displays the message
โ
Other devices forward but don't show it
- Each device has a Persistent ID (UUID)
- Friend requests include:
FRIEND_REQUEST:senderID:username - Accepted friends are stored locally
- Personal chats use persistent IDs to target messages
To prevent infinite message loops:
val messageHash = "$senderID:$messageContent".hashCode()
if (seenMessages.contains(messageHash)) {
return // Already seen, don't forward
}
seenMessages[messageHash] = currentTime
forwardToOtherPeers(message)- Public chat room visible to all connected devices
- Messages show sender's username
- Real-time message delivery
- Auto-scroll to latest messages
- Send friend requests using persistent IDs
- Accept/reject incoming requests
- Friends list persists across app restarts
- See online/offline status
- One-on-one conversations with friends
- Messages stored locally per friend
- Chat history persists across sessions
- Works even when friend is not directly connected (via mesh routing)
- No central server - all data stays on device
- Messages not stored on intermediate devices
- Each user has a unique persistent ID
- Friend system prevents spam
The project follows separation of concerns pattern:
UI Components (*.tsx)
- Pure presentational components
- No business logic
- Imports hooks and styles
Custom Hooks (use*.ts)
- State management
- Business logic
- Event listeners
- Network operations
Styles (*.styles.ts)
- StyleSheet definitions
- Separated from components
- Reusable style objects
Types (types/index.ts)
- Centralized TypeScript interfaces
- Shared across the app
- Type-safe development
Native Module (MeshNetworkModule.kt)
- Implements Google Nearby Connections API
- Handles device discovery and connections
- Manages message sending/receiving
- Forwards messages in mesh network
Storage Service (utils/storage.ts)
- AsyncStorage wrapper
- Manages persistent data
- Friend list storage
- Chat history per friend
Main Hook (useChatScreen.ts)
- Manages broadcast chat logic
- Handles peer connections
- Processes incoming messages
- Friend request system
- First-time setup
- Enter username
- Generates persistent ID
- One-time process
- Main chat room
- See all connected peers
- Send broadcast messages
- Add friends from peer list
- List of added friends
- Online/offline indicators
- Tap to open personal chat
- Pending friend requests
- One-on-one conversation
- Message history
- Send direct messages
- Connection status indicator
- View your username
- View persistent ID
- App information
- Clear data options
Broadcast Message:
"senderEndpointID|||senderUsername|||messageText"
Direct Message:
"DIRECT_MSG:targetPersistentID:messageText"
Friend Request:
"FRIEND_REQUEST:senderPersistentID:senderUsername"
Friend Accept:
"FRIEND_ACCEPT:senderPersistentID:senderUsername"
@meshage_username // User's display name
@meshage_persistent_id // Unique device ID
@meshage_friends // Friends list (JSON array)
@meshage_friend_requests // Pending requests (JSON array)
@meshage_chat_<friendID> // Chat history per friend
@meshage_onboarding_complete // Onboarding status- Install app on 3+ physical Android devices
- Open app on all devices
- Devices should auto-discover each other
- Send message from Device A
- Verify Device B and C receive it
- Move Device C out of range of Device A
- Verify Device C still receives messages via Device B (mesh routing)
- Add Device B as friend from Device A
- Accept friend request on Device B
- Open personal chat on Device A
- Send message
- Verify message appears on Device B
- Close and reopen app
- Verify chat history persists
- Ensure Location is enabled (required for Nearby Connections)
- Grant all required permissions
- Check that devices are within 100 meters
- Restart the app on both devices
- Check Android version (requires Android 6.0+)
- Check if devices are connected (peer list)
- Verify network status in app
- Check logs for errors:
adb logcat | grep Meshage - Ensure message format is correct
- Clear app data: Settings โ Apps โ Meshage โ Clear Data
- Reinstall the app
- Check Android version compatibility
- Review logcat for native errors
- Verify both devices have unique persistent IDs
- Check that devices are connected to mesh
- Ensure friend request message format is correct
- Check AsyncStorage for corrupted data
- Discovery Time: 2-5 seconds
- Connection Time: 1-3 seconds per peer
- Message Latency: <100ms (direct), <500ms (via mesh)
- Max Peers: ~8 simultaneous connections per device
- Range: Up to 100 meters (WiFi Direct)
- Battery Impact: Moderate (continuous scanning/advertising)
- End-to-end encryption
- File/image sharing
- Group chats
- Voice messages
- Message reactions
- Read receipts
- Typing indicators
- iOS support (using MultipeerConnectivity)
- Message search
- Export chat history
- Custom themes
- Profile pictures
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Your Name
- GitHub: @yourusername
- Email: your.email@example.com
- Google Nearby Connections API - For P2P connectivity
- React Native Community - For the amazing framework
- AsyncStorage - For persistent local storage
- All contributors and testers
Built with โค๏ธ using React Native
Empowering communication without boundaries