Open-source Flutter client for MeshCore LoRa mesh networking devices
  • Dart 95.5%
  • HTML 2.1%
  • Python 1.2%
  • C++ 0.4%
  • CMake 0.3%
  • Other 0.3%
Find a file
2026-09-27 22:48:48 -07:00
.github Harden Fastlane workflow and tidy store description 2026-09-27 12:22:52 -07:00
android Add notification replies, Android Auto support, and channel mute bell 2026-09-27 21:55:43 -07:00
assets Add ExportOptions.plist for App Store Connect configuration 2026-07-04 00:45:18 -07:00
docs Refresh documentation and update Dutch translation 2026-09-27 13:12:23 -07:00
documentation Add notification replies, Android Auto support, and channel mute bell 2026-09-27 21:55:43 -07:00
ios Refresh documentation and update Dutch translation 2026-09-27 13:12:23 -07:00
lib Add missing translations for all locales 2026-09-27 22:31:20 -07:00
linux Fix URL image preference scoping and cache behavior 2026-08-28 21:25:58 +02:00
macos Add ability to send images over lora 2026-08-10 23:20:46 -07:00
metadata/en-US Replace stale 13.txt changelog with release notes for build 16 2026-09-27 12:26:58 -07:00
scripts/security feat: add contact UI helpers and path editor for routing management 2026-06-11 00:07:12 -07:00
test Add notification replies, Android Auto support, and channel mute bell 2026-09-27 21:55:43 -07:00
tools Refresh documentation and update Dutch translation 2026-09-27 13:12:23 -07:00
web Initial commit: MeshCore Open Flutter client 2025-12-26 11:42:02 -07:00
windows Fix URL image preference scoping and cache behavior 2026-08-28 21:25:58 +02:00
.gitattributes Configure Git LFS for binary files 2025-12-31 22:24:06 -07:00
.gitignore chore: stop tracking .claude worktrees and ignore .claude/ 2026-06-11 00:10:49 -07:00
.gitmodules gitmodule cleanup 2026-03-05 02:26:37 -05:00
.metadata Initial commit: MeshCore Open Flutter client 2025-12-26 11:42:02 -07:00
.ruby-version add rbenv support 2026-02-19 11:17:58 -08:00
.swift-version feat: improve message matching logic and update notification IDs for advertisements 2026-03-14 09:44:37 -07:00
AGENTS.md Refresh documentation and update Dutch translation 2026-09-27 13:12:23 -07:00
analysis_options.yaml Honor manual disconnect and re-validate state after waiting 2026-09-17 23:05:43 +02:00
CLAUDE.md Refresh documentation and update Dutch translation 2026-09-27 13:12:23 -07:00
CONTRIBUTING.md Refresh documentation and update Dutch translation 2026-09-27 13:12:23 -07:00
flake.lock add flake.lock 2026-02-11 17:26:43 +01:00
flake.nix fix smaller copilot issues 2026-02-11 17:45:15 +01:00
l10n.yaml Add untranslated messages file and update localization keys 2026-01-19 19:13:22 -07:00
LICENSE Add MIT License to the project 2025-12-31 22:37:39 -07:00
mesh-icon.png add icon, also misc improvments 2025-12-30 20:04:53 -07:00
package.json wrangler deploy 2026-02-22 10:48:22 -08:00
pubspec.yaml Bump build number to 9.5.0+17 2026-09-27 22:45:54 -07:00
README.md Add notification replies, Android Auto support, and channel mute bell 2026-09-27 21:55:43 -07:00
TESTFLIGHT_GUIDE.md Refresh documentation and update Dutch translation 2026-09-27 13:12:23 -07:00
untranslated.json Add missing translations for all locales 2026-09-27 22:31:20 -07:00
wrangler.toml wrangler deploy 2026-02-22 10:48:22 -08:00

MeshCore Open

Open-source Flutter client for MeshCore LoRa mesh networking devices.

Overview

MeshCore Open is a cross-platform application for communicating with MeshCore LoRa mesh radios over Bluetooth Low Energy (BLE), USB serial, or TCP. The app enables long-range, off-grid communication through peer-to-peer messaging, public channels, and mesh networking capabilities.

Website: meshcoreopen.org

Get it on Obtainium

The web client runs in Chrome (and Chromium browsers that identify as Chrome, such as Edge or Brave) and connects over USB via Web Serial. BLE and TCP are not available in the browser. Firefox and Safari do not support Web Serial.

Install and first use

Use the installation website for available downloads, Obtainium, and the web client. Building from source is covered below.

  1. Use a MeshCore radio running companion firmware with the transport you intend to use.
  2. Open the app, scan for BLE devices or select USB/TCP, and connect.
  3. After synchronization, open a channel to broadcast or open Contacts to send a direct message. Peers need compatible radio settings; channels need the same PSK.

See the user documentation, connection guide, and troubleshooting.

Screenshots

Contact list

Contacts

Direct message conversation

Chat

Message reactions

Reactions

Mesh node map

Map

Channel list

Channels

Features

Core Functionality

  • Direct Messaging: Private encrypted conversations with individual contacts
  • Channels: Public, hashtag, private, and community channels
  • Mesh Images: Send compressed images in channel chat with optional recovery packets (guide)
  • Regions: Scope channel floods and reply using a message’s known region (guide)
  • Translation: Optional on-device incoming and pre-send translation
  • Contact Management: Organize contacts, track last seen times, and manage conversation history
  • Contact Groups: Create custom groups to organize your mesh network contacts
  • Message Reactions: React to messages with emoji responses
  • Message Replies: Thread conversations with inline reply functionality
  • Android Auto & Watches: Hear messages and reply by voice in Android Auto, or reply from the notification shade and Wear OS/Galaxy watches (guide)
  • Channel Muting: Mute a channel from its chat screen, the channel list, or its notification

Mesh Network

  • Path Visualization: View routing paths and signal quality for each contact
  • Route Management: Manual path overriding and automatic route rotation
  • Signal Metrics: Real-time SNR (Signal-to-Noise Ratio) tracking
  • Node Discovery: Automatic detection of nearby mesh nodes
  • Repeater Support: Connect to and manage repeater nodes for extended range

Map & Location

  • Live Map View: Real-time visualization of mesh network nodes on an interactive map
  • Node Filtering: Filter by node type (chat, repeater, sensor) and time range
  • Location Sharing: Share GPS coordinates and custom markers with contacts
  • Offline Maps: Download map tiles for offline use in remote areas using a configured Stadia Maps source and API key; see map setup
  • MGRS Coordinates: Support for Military Grid Reference System coordinate format

Device Management

  • BLE, USB, TCP Connection: Scan and connect to MeshCore devices via Bluetooth, USB or TCP
  • Device Settings: Configure radio parameters, power settings, and network options
  • Battery Monitoring: Real-time battery status with chemistry-specific voltage curves

Repeater Hub

  • CLI Access: Full command-line interface to repeater nodes
  • Settings Management: Configure repeater behavior, power limits, and network settings
  • Statistics Dashboard: View repeater traffic, connected clients, and system health
  • Remote Management: Administer repeaters from anywhere on the mesh network

Technical Details

Architecture

  • Framework: Flutter (web deployment pins 3.41.2); Dart SDK constraint ^3.9.2
  • State Management: Provider pattern with ChangeNotifier
  • BLE Protocol: Nordic UART Service (NUS) over Bluetooth Low Energy
  • Storage: JSON in SharedPreferences for messages and contacts; files for models, images, and map caches
  • Encryption: End-to-end encryption for private messages using the MeshCore protocol

Platform Support

Feature Android (ARM64) iOS (16.4+) Linux Windows macOS Web
BLE companion ✅ ✅ ✅ ✅ ✅ ❌
USB companion ✅ ❌ ✅ ✅ ✅ ✅
(Web Serial, Chrome)
TCP companion ✅ ✅ ✅ ✅ ✅ ❌
Core Functionality ✅ ✅ ✅ ✅ ✅ ✅
Mesh Network ✅ ✅ ✅ ✅ ✅ ✅
Map & Location ✅ ✅ ✅ ✅ ✅ ✅
Device Management ✅ ✅ ✅ ✅ ✅ ✅
Repeater Hub ✅ ✅ ✅ ✅ ✅ ✅
Notification replies ✅
(incl. Android Auto, watches)
❌ ❌ ❌ ❌ ❌

The matrix describes implemented functionality, not a guarantee that every feature has been tested on every device. Web device connections use Web Serial and require Chrome and a secure origin. Image inference and translation require native runtimes and are unavailable on web. Android APKs currently include only arm64-v8a; the minimum Android API follows the Flutter SDK used to build.

Dependencies

Package Purpose
flutter_blue_plus Bluetooth Low Energy communication
provider State management
shared_preferences Local key-value storage (scoped per device)
flutter_map Interactive map display
latlong2 Geographic coordinate handling
flutter_local_notifications Background notification support
pointycastle Cryptographic operations
llamadart On-device LLM message translation
intl Internationalization and date formatting

Getting Started

Prerequisites

  • Flutter SDK; web deployment currently pins 3.41.2. The Dart SDK constraint is ^3.9.2 (see pubspec.yaml).
  • Android Studio / Xcode (for mobile development)
  • A MeshCore-compatible LoRa device

Build from source

  1. Clone the repository

    git clone https://github.com/zjs81/meshcore-open.git
    cd meshcore-open
    
  2. Install dependencies

    flutter pub get
    
  3. Run the app

    flutter run
    

Web (self-host)

Use a Chromium browser. Device APIs are origin-gated, so serve the build over HTTPS.

flutter build web --release

Then serve build/web/ from your own host. See install/web for browser support and caveats.

Building for Release

Android APK:

flutter build apk --release

iOS:

flutter build ios --release

Project Structure

lib/
├── main.dart                    # App entry point
├── connector/
│   ├── meshcore_connector.dart  # BLE communication & state management
│   ├── meshcore_protocol.dart   # Protocol definitions & frame parsing
│   └── meshcore_uuids.dart      # NUS UUIDs; reference name prefixes (not filters)
├── screens/
│   ├── scanner_screen.dart      # Device scanning (home screen)
│   ├── contacts_screen.dart     # Contact list
│   ├── chat_screen.dart         # Direct messaging
│   ├── channels_screen.dart     # Public channels
│   ├── map_screen.dart          # Network visualization map
│   ├── settings_screen.dart     # Device settings
│   └── repeater_hub_screen.dart # Repeater management
├── models/
│   ├── contact.dart             # Contact data model
│   ├── message.dart             # Message data structure
│   └── channel.dart             # Channel definitions
├── services/
│   ├── notification_service.dart      # Local OS notifications
│   ├── message_retry_service.dart     # Automatic message retry
│   ├── background_service.dart        # Background BLE connection
│   └── map_tile_cache_service.dart    # Offline map storage
└── storage/
    ├── message_store.dart       # Message persistence
    ├── contact_store.dart       # Contact persistence
    └── unread_store.dart        # Unread message tracking

BLE Protocol

Nordic UART Service (NUS)

  • Service UUID: 6e400001-b5a3-f393-e0a9-e50e24dcca9e
  • RX Characteristic: 6e400002-b5a3-f393-e0a9-e50e24dcca9e (Write to device)
  • TX Characteristic: 6e400003-b5a3-f393-e0a9-e50e24dcca9e (Notify from device)

Device Discovery

BLE scanning filters on the Nordic UART Service UUID, so devices with custom names can be found. Known name prefixes in lib/connector/meshcore_uuids.dart are reference values, not discovery filters.

Message Format

Messages are transmitted as binary frames using a custom protocol optimized for LoRa transmission. See the protocol reference for frame definitions.

Configuration

App Settings

  • Theme: System default, light, or dark mode
  • Language: Use one of 18 languages (English, Chinese, French, Spanish, Portuguese, German, Dutch, Polish, Swedish, Italian, Slovak, Slovenian, Bulgarian, Russian, Ukrainian, Hungarian, Japanese, Korean)
  • Notifications: Configurable for messages, channels, and node advertisements; per-channel muting; reply, mark-as-read, and mute actions on Android notifications and watches (reply and mark-as-read in Android Auto)
  • Battery Chemistry: Support for NMC, LiFePO4, LiPo, and LiPo HV battery types
  • Message Retry: Automatic retry with configurable path clearing

Device Settings

  • Radio Power: Transmit power adjustment within the connected device’s supported range
  • Frequency: LoRa frequency configuration
  • Bandwidth: Channel bandwidth selection
  • Spreading Factor: Range vs. speed trade-off
  • Flood Scope: Region selection for channel floods

Contributing

Read CONTRIBUTING.md before starting a contribution. Discuss changes in an issue first and base PRs on dev.

Run the checks used by CI:

dart format --output=none --set-exit-if-changed .
flutter analyze --fatal-infos --fatal-warnings
flutter test

Development Guidelines

  • Follow the Flutter style guide
  • Use Material 3 design components
  • Write clear commit messages
  • Test on the platforms affected by your change before submitting PRs

Code Style

  • Prefer StatelessWidget with Consumer for reactive UI
  • Use const constructors where possible
  • Keep functions small and focused
  • Avoid premature abstractions
  • Run dart format on all changes before submitting

Support

For issues, questions, or feature requests, please open an issue on GitHub: https://github.com/zjs81/meshcore-open/issues

Donate

If you find MeshCore Open useful and would like to support development, you can donate Solana or other Solana tokens:

Solana Address: F15YanjZj96YTBtKJYgNa8RLQLCZkx5CEwogPWkqXeoQ

Monero Address: 453TxnpUqjkJtXxzdjMsrgERNkBRXEGamPbpC45ENrvKAk9tH7kZbxWF82Hz66etgDZyXFPEBU2JUEqhLeJyWt9kBvTVy5m

Bitcoin Address: bc1qh45x28v8dslcg4v4upmqd9g0mvc3lnyffmyzr5

Your support helps maintain and improve this open-source project!

License

MeshCore Open is available under the MIT License.

Acknowledgments

SWHID and Archive badge

SWH SWH