zjs81/meshcore-open

Open-source Flutter client for MeshCore LoRa mesh networking devices

Dart

637

919 commits

updated Oct 12, 2026

See the code

README

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 · Network map: map.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

FeatureAndroid (ARM64)iOS (16.4+)LinuxWindowsmacOSWeb
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

PackagePurpose
flutter_blue_plusBluetooth Low Energy communication
providerState management
shared_preferencesLocal key-value storage (scoped per device)
flutter_mapInteractive map display
latlong2Geographic coordinate handling
flutter_local_notificationsBackground notification support
pointycastleCryptographic operations
llamadartOn-device LLM message translation
intlInternationalization 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

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

zjs81/meshcore-open

Open-source Flutter client for MeshCore LoRa mesh networking devices

Dart

637

919 commits

updated Oct 12, 2026

See the code

README

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 · Network map: map.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

FeatureAndroid (ARM64)iOS (16.4+)LinuxWindowsmacOSWeb
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

PackagePurpose
flutter_blue_plusBluetooth Low Energy communication
providerState management
shared_preferencesLocal key-value storage (scoped per device)
flutter_mapInteractive map display
latlong2Geographic coordinate handling
flutter_local_notificationsBackground notification support
pointycastleCryptographic operations
llamadartOn-device LLM message translation
intlInternationalization 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

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

Significant stargazers

Brandon Philips

1,584 followers · starred Jan 2026

Kristjan ESPERANTO

63 followers · starred Apr 2026

Quentin Smith

84 followers · starred Apr 2026

Filip Hracek

4,285 followers · starred Feb 2026