Web Serial Connection
Web Serial mode lets the browser hold the radio's USB serial port directly, instead of the MeshDash server process. This is useful when running MeshDash on a remote server (e.g. a VPS) and physically connecting the radio to your local PC.
How It Works
[Radio USB cable]
|
[Your PC browser (Chrome/Edge)]
| Web Serial API (navigator.serial)
| Meshtastic binary framing (magic bytes 0x94 0xC3)
v
[MeshDash server] ← /api/webserial/packet (browser pushes decoded packets)
| /api/webserial/send (browser pulls messages to send)
v
[Dashboard frontend] ← SSE stream (same as normal)
The browser reads raw bytes from the serial port, decodes the Meshtastic protobuf framing, and POSTs decoded packets to /api/webserial/packet. The server stores them and emits them over SSE exactly as if the server had received them directly over serial.
For outbound messages, the browser polls /api/webserial/send to collect queued messages and writes them to the serial port. Because of this, POST /api/messages is transparently intercepted by a window.fetch patch — the message goes through the browser serial port, not the server's radio connection.
Enabling Web Serial Mode
Step 1: Configure in Settings
Go to Settings → Primary Radio Connection → Protocol and select WEB SERIAL (USB — browser-direct) ⚡ BETA. Click Save Config then Restart Service.
After restart, the server will no longer attempt to open a serial port. A WEB SERIAL button appears in the topbar.
Step 2: Connect the Browser
Click the WEB SERIAL button in the topbar. The connection wizard opens with three states:
Supported USB Vendor IDs
The port picker filters to known Meshtastic-compatible chipsets:
| Vendor ID | Chip | Common devices |
|---|---|---|
0x10C4 | Silicon Labs CP210x | T-Beam v0.7, older TTGO |
0x1A86 | CH340 / CH341 | Various budget boards |
0x0403 | FTDI FT232 | Older Meshtastic boards |
0x239A | Adafruit / TinyUSB | Adafruit Feather boards |
0x303A | Espressif ESP32-S3 | T-Beam S3, XIAO S3, newer boards |
If your device is not listed, you may still be able to connect by dismissing the filtered picker (some browsers allow viewing all ports).
Connection Process (Technical)
- Browser opens port at the selected baud rate
- DTR and RTS signals are released (
setSignals({dataTerminalReady: false, requestToSend: false})) to avoid triggering an ESP32 reset - Backend
GET /api/webserial/wakeupis called — returns the Meshtasticwant_config_idprotobuf frame as bytes - That frame is written to the serial port to prompt the radio to send its node database
- Backend is notified via
/api/webserial/status(connected) - The read loop begins: raw bytes are accumulated, magic bytes
0x94 0xC3mark packet boundaries, and complete packets are POSTed to/api/webserial/packet
Topbar Status Indicators
While Web Serial is active:
- The WEB SERIAL button remains visible and its label changes to indicate connection state
- A green stats pill appears showing
RX: Npackets and bytes - If disconnected, the pill disappears and the WEB SERIAL button returns to its default state
- The Settings view shows an ACTIVE SESSION box under the Web Serial option with live stats and a Disconnect button
Compatibility Check
When the Settings view loads Web Serial mode, it displays a compatibility banner:
- Supported — Chrome or Edge 89+ on HTTPS/localhost
- Not Supported — Firefox, Safari, or HTTP (non-localhost)
- Unknown — Browser doesn't expose
navigator.serial
Disconnecting
Click ⏏ DISCONNECT PORT in the Settings active session box, or call window.WebSerialBridge.disconnect(). This:
- Cancels the read loop
- Releases the writer lock
- Closes the port
- Notifies the backend (
/api/webserial/status→disconnected) - Updates the topbar UI
How Data Flows (WebSerial Mode Detail)
The complete data path when a packet is received in WebSerial mode:
[Radio sends packet over USB serial]
│
[Browser read loop accumulates bytes]
│ detects magic bytes 0x94 0xC3 + length
[Browser posts raw protobuf to /api/webserial/packet]
│
[Server decodes protobuf via Meshtastic SDK]
│
[Packet enters packet_queue — same as native serial]
│
[packet_processing_worker processes it]
├── DB save (packets, messages, telemetry, positions)
├── node_update (meshState + DB)
└── SSE broadcast → browser dashboard updates
For outbound messages sent while WebSerial is active:
[User clicks TRANSMIT in dashboard]
│
[POST /api/messages intercepted by fetch patch]
│
[WebSerialBridge.sendText() called directly]
│
[Message encoded to Meshtastic protobuf in browser]
│
[Bytes written to serial port writer]
│
[Radio transmits over mesh]
Baud Rate Selection
Most Meshtastic devices use 115200 baud (the default). Some T-Beam variants and custom firmware builds use 921600. If you connect but see no packets after the wakeup frame, try the alternative baud rate. The modal's baud rate dropdown offers: 9600, 115200, 230400, 460800, 921600.
Simultaneous Server and Browser Connection
MESHTASTIC_CONNECTION_TYPE=SERIAL (or TCP/BLE) while also using Web Serial. Only one process can hold a serial port at a time. If the server is already connected over serial, the browser will fail to open the port with a "Device already in use" error. Always set the config to WEBSERIAL before using the browser bridge.