Day One: Building a Mesh Radio Companion

First commit today. The idea: a companion app for Meshtastic mesh radios that does not depend on the official app. Something built for the way I actually use these devices in the field.

Why build this?

The official Meshtastic app works. But every time I wanted to add a feature — automations, better node tracking, presence awareness — I hit walls. The codebase is designed around firmware updates and configuration, not live mesh interaction. Fair enough. Different goals.

So: build my own. Flutter for cross-platform (iOS and Android from one codebase), BLE for the radio link, and a dark sci-fi aesthetic because if you are going to stare at a screen in the dark, it should look good.

What works so far

One hard day of coding and the skeleton is up:

  • BLE scanning — finds Meshtastic devices, shows signal strength with visual indicators
  • Connection management — connects, subscribes to notifications, handles the config download sequence
  • Protocol layer — parses FromRadio protobufs, sends ToRadio, handles the want_config handshake
  • Transport abstractionrequiresFraming flag on the transport layer so we can add USB serial later without touching protocol code
  • Dark theme — the whole UI is dark from day one, no afterthought migration later

The transport abstraction was the first real architectural decision. BLE sends raw protobufs. USB serial needs framing (start bytes, length prefix, CRC). By putting that flag on the transport interface now, the protocol layer never needs to know which physical link it is talking over.

abstract class DeviceTransport {
  bool get requiresFraming;
  Stream<List<int>> get dataStream;
  Future<void> sendBytes(List<int> data);
}

What is next

Messages, channels, node tracking. The mesh is a network — the app needs to show the network, not just the radio.