MeshLink is a peer-to-peer (P2P), delay-tolerant networking application designed for communication in infrastructure-denied environments (e.g., flood zones, war zones, or remote areas without cellular coverage).
It utilizes a Store-and-Forward architecture to persist messages locally and opportunistically sync them with nearby peers, effectively turning every device into a data mule.
MeshLink consists of two main components:
A lightweight WebSocket relay server built with Bun that simulates nearby devices for testing. In production, this would be replaced by true peer-to-peer mesh networking, but for development and testing, this relay allows multiple clients to discover and communicate with each other as if they were nearby.
A cross-platform mobile application built with React Native and Expo, featuring local-first data persistence using WatermelonDB. The app uses the relay server to simulate mesh network behavior during development.
graph LR
A[Mobile Client 1] <-->|WebSocket| C[Development Relay Server]
B[Mobile Client 2] <-->|WebSocket| C
D[Mobile Client N] <-->|WebSocket| C
A -.->|Local DB| E[(WatermelonDB)]
B -.->|Local DB| F[(WatermelonDB)]
D -.->|Local DB| G[(WatermelonDB)]
Production Environment (Future):
graph TB
subgraph "Mesh Network Topology"
A[Mobile Device 1]
B[Mobile Device 2]
C[Mobile Device 3]
D[Mobile Device 4]
E[Mobile Device 5]
A <-->|Bluetooth/WiFi Direct| B
A <-->|Bluetooth/WiFi Direct| C
B <-->|Bluetooth/WiFi Direct| C
B <-->|Bluetooth/WiFi Direct| D
C <-->|Bluetooth/WiFi Direct| E
D <-->|Bluetooth/WiFi Direct| E
A -.->|Local DB| DB1[(WatermelonDB)]
B -.->|Local DB| DB2[(WatermelonDB)]
C -.->|Local DB| DB3[(WatermelonDB)]
D -.->|Local DB| DB4[(WatermelonDB)]
E -.->|Local DB| DB5[(WatermelonDB)]
end
style A fill:#4CAF50
style B fill:#2196F3
style C fill:#FF9800
style D fill:#9C27B0
style E fill:#F44336
Note
In production, devices communicate directly via Bluetooth or WiFi Direct (P2P mesh), creating a decentralized network. Each device acts as both a client and a relay, forwarding messages to extend network reach. The development relay server above is only used for testing.
- β Real-time peer-to-peer messaging via WebSocket relay
- β Local-first data persistence with WatermelonDB
- β Message status tracking (pending, synced)
- β Automatic reconnection and message queue synchronization
- β Connection status indicator
- π― Local-First Architecture: Messages are stored locally first, then synchronized
- π Automatic Sync: Pending messages are automatically sent when connection is restored
- π Resilient Connections: Auto-reconnect with exponential backoff
- π Reactive UI: WatermelonDB observables for real-time UI updates
- π¨ Cross-Platform: Runs on iOS, Android, and Web using React Native
meshlink/
βββ server/ # WebSocket relay server
β βββ index.ts # Main server implementation
β βββ package.json # Server dependencies
β βββ tsconfig.json # TypeScript configuration
β
βββ mobile/ # React Native client
β βββ src/
β β βββ core/
β β β βββ db/ # WatermelonDB setup and models
β β β β βββ index.ts
β β β β βββ schema.ts
β β β β βββ model/
β β β β βββ Message.ts
β β β βββ transport/ # Network layer
β β β βββ Transport.interface.ts
β β β βββ WebSocketTransport.ts
β β βββ hooks/
β β β βββ useMeshNetwork.ts # Main networking hook
β β βββ ui/
β β βββ MessageBubble.tsx # Message UI component
β β βββ ConnectionBanner.tsx
β βββ App.tsx # Main application
β βββ package.json # Mobile dependencies
β βββ app.json # Expo configuration
β
βββ README.md # This file
- Bun v1.3.4 or later (for server)
- Node.js v18+ (for mobile)
- Expo CLI
- iOS Simulator, Android Emulator, or physical device
-
Navigate to the server directory:
cd server -
Install dependencies:
bun install
-
Start the relay server:
bun run index.ts
The server will start on ws://localhost:8080
By default, the server runs on port 8080. To change this, modify the PORT constant in server/index.ts:
const PORT = 8080; // Change to your desired port-
Navigate to the mobile directory:
cd mobile -
Install dependencies:
npm install
-
Start the development server:
npm start
-
Run on your preferred platform:
- iOS:
npm run ios - Android:
npm run android - Web:
npm run web
- iOS:
To connect to a different relay server, update the WebSocket URL in mobile/src/core/transport/WebSocketTransport.ts:
// Change the server address/port as needed
private url = 'ws://YOUR_SERVER_IP:8080';Note: When testing on physical devices, replace
localhostwith your computer's local IP address.
-
Sending a Message:
User Input β Save to Local DB (pending) β Broadcast via WebSocket β Update to synced -
Receiving a Message:
WebSocket receives β Save to Local DB (synced) β UI auto-updates via observable -
Offline/Reconnect:
Connection lost β Messages queued as pending β Connection restored β Auto-sync pending messages
- WebSocket server using Bun's native WebSocket support
- Simulates nearby device discovery for testing mesh networking
- Topic-based pub/sub pattern (
global-meshtopic) - Device ID tracking via headers or auto-generated IDs
- Connection lifecycle management
- Lightweight development tool (production would use true P2P mesh)
Database Layer (src/core/db/)
- WatermelonDB for local-first storage
- Message model with status tracking
- Reactive queries for UI updates
Transport Layer (src/core/transport/)
- Abstract transport interface
- WebSocket implementation with auto-reconnect
- Connection status callbacks
- Message broadcast/receive handling
Hook Layer (src/hooks/useMeshNetwork.ts)
- React hook for network operations
- Message synchronization logic
- Connection state management
- Database write operations
UI Layer (src/ui/ & App.tsx)
- Message list with real-time updates
- Message bubbles with sender differentiation
- Connection status banner
- Input field and send functionality
The server is intentionally minimalistic and serves as a testing simulator. Key features:
- Simulates nearby devices for mesh network testing
- No external dependencies (uses Bun's built-in WebSocket)
- Topic-based broadcasting mimics local mesh discovery
- Device ID tracking for peer identification
- Simple message relay without persistence
Note
In production, the relay server would be replaced by true peer-to-peer mesh networking (Bluetooth, WiFi Direct, etc.). This relay exists purely to facilitate development and testing.
To add features:
- Message persistence: Add SQLite or other database
- Authentication: Validate device IDs or add JWT
- Message routing: Implement private channels or direct messaging
The mobile app uses a clean, layered architecture:
- Core: Database and transport implementations
- Hooks: Business logic and state management
- UI: React components
To extend:
- Add more message types (images, files, etc.)
- Implement user profiles
- Add end-to-end encryption
- Create chat rooms or channels
- Start the server
- Use a WebSocket client (e.g.,
websocator browser DevTools):websocat ws://localhost:8080
- Send test messages in JSON format:
{"type":"TEXT","payload":"Hello World","senderId":"test-1","timestamp":1234567890}
- Run multiple instances (e.g., iOS + Android simulators)
- Send messages from one device
- Verify they appear on other devices
- Test offline scenarios:
- Stop the server
- Send messages (should show as pending)
- Restart server
- Verify messages sync automatically
- Bun - JavaScript runtime and WebSocket server
- TypeScript - Type safety
- React Native - Cross-platform mobile framework
- Expo - Development platform and tooling
- WatermelonDB - Reactive local database
- React - UI library
- TypeScript - Type safety
Warning
This is a development/prototype implementation. For production use, consider:
- Authentication: Implement proper user authentication (JWT, OAuth, etc.)
- Encryption: Add TLS/SSL for WebSocket connections
- Validation: Sanitize and validate all incoming messages
- Rate Limiting: Prevent spam and abuse
- Message Encryption: Implement end-to-end encryption for privacy
- Authorization: Add access control for different message types/channels
Problem: Server won't start on port 8080
Error: Address already in useSolution: Change the PORT in server/index.ts or kill the process using port 8080
Problem: Cannot connect to server from physical device
Solution: Replace localhost with your computer's local IP in the WebSocket URL
Problem: Messages not syncing Solution: Check that both server and client are running, and verify the WebSocket URL is correct
Problem: WatermelonDB errors Solution: Clear the app data or reinstall the app to reset the database
- Basic relay server
- WebSocket transport
- Local database persistence
- Message status tracking
- Auto-reconnection
- Connection status UI
- User authentication
- End-to-end encryption
- Media messages (images, files)
- Message delivery confirmations
- Typing indicators
- Read receipts
- True peer-to-peer mesh networking (Bluetooth/WiFi Direct)
- Group chats/channels
- Voice/video calls
- Push notifications
- Message search
- Message reactions
- User profiles and avatars
- HQ Command Center - Centralized monitoring and management dashboard
- Real-time network topology visualization
- Message analytics and monitoring
- Device/peer management
- Network health metrics
- Administrative controls
MIT
For issues or questions, please create an issue in the repository.
Built with β€οΈ using Bun, React Native, and WatermelonDB