Mesh-Client
Cross-platform Electron desktop client for Meshtastic and MeshCore on macOS, Linux, and Windows with BLE, USB serial, Wi‑Fi/TCP, MQTT, local SQLite history, routing diagnostics, and 16-language UI.

For everyone, everywhere. We welcome community participation and collaboration in the development of this project!
Why
Mesh-Client: The Universal Desktop Suite for Mesh Networks
Reliable Desktop Power. Local Persistence. Total Insight.
While official mobile apps cover the basics, desktop power users often face a fragmented ecosystem: limited app availability for MeshCore, inconsistent support across operating systems, and persistent sync issues on macOS. Mesh-Client fills those gaps with a high-performance desktop experience.
With a dedicated local SQLite database, Mesh-Client keeps message history and mesh logs durable across restarts and sync failures. It provides one reliable hub for both Meshtastic and MeshCore firmware, delivering a unified workflow regardless of protocol or hardware.
Why Mesh-Client?
- True message persistence: Local SQLite storage for reliable long-term history, without lost chats or broken logs.
- Universal protocol support: One consistent interface for both Meshtastic and MeshCore devices.
- Advanced mesh visibility: Routing diagnostics and mesh health insight that mobile apps often skip.
- Desktop-first workflow: MQTT integration and a full-featured interface for power users.
- Cross-platform stability: A feature-rich experience across macOS, Linux, and Windows.
From real-time diagnostics to permanent message archives, Mesh-Client delivers the desktop visibility serious mesh users require.
Known Bugs:
- Linux BLE: uses Web Bluetooth (Chromium's built-in BLE API), with a user-visible picker and user gesture requirement to select a device. MeshCore may prompt for the radio's PIN and run OS-level pairing (
bluetoothctl) before the connection completes when BlueZ reports the device as not paired (see docs/development-environment.md).
Visuals
Screenshots
Key Features
Meshtastic Features
Radio & Channel Configuration
- Edit channels: name, PSK, and role; 18 region presets and 7 modem presets
- Channel URL import/export (Radio tab): generate, copy, preview, and apply
https://meshtastic.org/e/#… or meshtastic:// links (same ChannelSet protobuf format as the Android/web clients); replace all channels or add-only mode
- Device roles: Client, Router, Tracker, Sensor, TAK, and more
- Display, Bluetooth, and Power settings on the Radio tab (screen/LED, pairing, sleep, and power limits)
- Per-channel MQTT gateway uplink (RF → MQTT)
- Administration tab: reboot, shutdown, factory reset, NodeDB reset (optional preserve favorites), reboot-to-OTA, and enter DFU (local radio only; OTA/DFU disabled when Configure node targets a remote node)
MQTT
- Subscribe to a broker to receive mesh traffic over the internet; AES-128/256-CTR decryption (16- or 32-byte channel PSKs), automatic RF deduplication, cross-transport chat dedup (when the same message arrives on MQTT and RF within ~10 minutes, one bubble is kept and the transport badge upgrades to both), 10-minute reconnect delay after failed attempts (recovers faster on connack timeout), and an active node cache that periodically refreshes presence information so MQTT-only and RF+MQTT nodes stay visible even when your radio is offline
- Channel PSKs on the Connection tab: base64 keys per line (optional
ChannelName=base64 for MQTT-only channels); multiple keys per channel name are supported; LongFast default is always tried; keys from the Radio tab sync automatically when the radio is connected (custom named keys are not overwritten by the default public PSK on sync)
- MQTT-only chat identity: when sending without a connected radio, outbound
from uses your last known RF node id when available, otherwise a stable per-install virtual id (persisted in app settings)
- Enable TLS (mqtts / wss) toggle for private brokers (not only port 8883/443); optional Allow insecure TLS for self-signed or non–public CA chains
- Per-channel MQTT uplink (RF → MQTT) uses each channel’s real name and PSK when publishing
- Transport indicator (RF / MQTT / both) on received messages; MQTT messages are shown in chat but not rebroadcast over RF
- Enter your broker URL, topic, and optional credentials in the MQTT section of the Connection tab; settings persist across sessions
Module Configuration
- Telemetry module (device, environment, air quality intervals), MQTT relay, Serial, External Notification, Store & Forward, Range Test, Canned Messages, Neighbor Info, Ambient Lighting, Detection Sensor, Pax Counter, Remote Hardware, Traffic Management, TAK (when firmware exposes the module key), and RTTTL (ringtone); editable from the Modules tab in firmware-dependent order (not strictly alphabetical)
- ConfigApplyNotice at the top of Radio, Modules, and Security reminds you that changes persist to the device and may require reboot; Apply stays disabled until each config slice hydrates from the device so defaults cannot overwrite live settings
- Remote Hardware (GPIO): configure pins and apply module settings; live GPIO status stream when the module is enabled
- Module status displays: Range Test, Serial, Store & Forward, Remote Hardware (GPIO), and IP Tunnel (status-only) show packet counts and last-received timestamps when the corresponding module is enabled on the device
- Store & Forward chat history: after RF configure, the client may request
CLIENT_HISTORY on the first primary router heartbeat (capped messages/window, 15 min cooldown, 5 min offline gate; opt-out in App settings). Use Catch up from Store & Forward in Chat for manual fetch. Replayed text shows a Store & Forward badge; MQTT reconnect floods within ~30 s are treated as history and deduped
Security
- Meshtastic — Security (PKI) tab (between Telemetry and App): admin / PKI key management; backup, restore, regenerate, and apply keys and related toggles from the device.
- MeshCore — Security tab (partial): per-node key backup / restore (full public + private pair), sign data, export/import private key. Meshtastic PKI admin sections are hidden (
hasSecurityPanel is true for both protocols; capabilities differ).
- DM / device key backup / restore: Backup Keys encrypts the connected local radio’s public and private keys into a per-node slot (
localStorage, OS keychain via safeStorage). Meshtastic indexes by nodeNum; MeshCore by nodeId. Backing up a second radio does not overwrite the first. Restore Keys applies the archive for the connected node; Restore from backup… picks any archived entry (factory reset / node id change). Hidden for remote configure targets. See Key backup and cryptography (includes backing up before moving Meshtastic nodes to MeshCore).
- PKC remote node administration (Meshtastic, firmware 2.5+): Configure node selector on Radio, Modules, Security, and Administration tabs to edit another node’s settings through your connected local radio; Configure node remotely from node detail when a per-node admin key is saved; Copy public key in Security for one-time trust setup. Paste a remote node’s admin public key in node detail (base64,
base64:…, or 64-char hex). PKI uses the mesh NodeDB key when present, with stored admin-key fallback. Requires a connected local Meshtastic radio — MQTT-only sessions cannot administer remote nodes.
Network Diagnostics
- Network health: status band Healthy / Attention / Degraded plus error and warning counts. Degraded applies only when routing error count ≥ 3; fewer errors use Attention so small issues don't paint the whole panel red
- Single table from
diagnosticRows (routing trace rows + RF rows), searchable; rows persist across sessions with an optional restore banner; max age (1–168 hours) trims stale routing (24 h default) and RF (1 h default) rows
- Mesh congestion attribution: orange banner when mesh-wide routing stress is present; duplicate-traffic block in node detail when relevant
- Routing anomaly detection: hop_goblin (distance-proven over-hopping), bad_route (high duplication), route_flapping / path_instability (MeshCore PathUpdated events), impossible_hop, weak_link (MeshCore per-hop SNR from trace); with remediation suggestions and severity levels
- Channel Utilization History: 24h CU timeline chart for the connected node in DiagnosticsPanel
- Anomaly badges inline in node list; status aura circles on the map; congestion halos toggle; global and per-node MQTT ignore
- Environment Profile segmented control; Standard (3 km), City (1.6× threshold), Canyon (2.6× threshold)
See Diagnostics Reference for a full reference on what triggers each finding and how to interpret it.
Environment Telemetry
- Push-based environment charts (temperature, humidity, pressure, air quality) from Meshtastic telemetry packets, displayed in the Telemetry tab
Packet Redundancy
- Per-node redundancy score derived from the last 20 observed packets;
+N echo count in the node list; collapsible Path History in node detail
TAK Server (CoT Gateway) (Meshtastic only)
- TAK tab (between Security and App): broadcast mesh node positions as Cursor on Target (CoT) XML events over TLS TCP (port 8089)
- Enables ATAK, WinTAK, and iTAK clients to see mesh nodes on their tactical maps
- Certificate management: self-signed CA + server + client certificates via node-forge; regenerate anytime from the TAK tab
- Data package generator: export ATAK-compatible (ca.pem, client.p12, connection.pref) for direct import on TAK devices
- Auto-start option (off by default); status indicator in header when running
- ATAK Plugin Messages: incoming ATAK plugin packets from mesh nodes are displayed in the TAK tab with sender node and packet counts
Features Available on Both Protocols
Connectivity
- Bluetooth LE: pair wirelessly; on macOS/Windows, startup auto-reconnect can run without a user gesture (Noble backend). On Linux, Web Bluetooth requires user gesture and picker selection.
- USB Serial: plug in via USB; auto-reconnects silently on startup (saved port signature matches the same physical device across re-enumeration)
- WiFi / HTTP / TCP: connect to network-enabled nodes; saves last address for quick reconnect
- Dual-mode: both Meshtastic and MeshCore run simultaneously; use the protocol switcher pill in the header to switch which view is active (the inactive protocol stays connected in the background); per-protocol unread badges (Meshtastic = green, MeshCore = cyan); passive toast notifications when the inactive protocol receives messages
- Connection status in header: device, MQTT, and TAK indicators pulse red after an unexpected disconnect; manual stop/disconnect stays gray; in-progress connect keeps yellow
Chat
- Send/receive messages across channels with per-transport delivery badges and delivery ACK / failure states
- Durable outbox: outgoing messages are queued in SQLite and retried until delivered; survive app restarts and connection drops
- Long message chunking: messages over the payload limit are auto-split into sequential
[N/T]-prefixed chunks (word-boundary split, max 9 chunks); MeshCore MQTT-only connections are guarded from sending when no RF path is available
- Shared composer (
ChatComposer): drafts, mentions, chunking, spellcheck, and emoji picker used by Chat and MeshCore Rooms; right‑click misspelling replacements (Electron spellchecker for both protocols)
- Emoji reactions / tapbacks: Meshtastic — 12 quick-p