neel sani

software engineer

<- back

mavlink in the browser (because nobody else did)

june 20246 min read

nobody had a proper mavlink parser that worked reliably in the browser. so i wrote one.

the problem

every existing lib was either node-only, c++ with no wasm, or just broken. i needed live drone telemetry in the browser — multiple operators watching the same mission, no backend, pure client-side. webserial/webusb → mavlink → react.

why browser

most mavlink libs target embedded or ground stations. browsers got nothing. the few js attempts:

  • assumed node buffer (dead on arrival)
  • no type safety
  • couldn't handle dialect switching
  • blew up on large parameter responses

how it works

state machine chewing through binary mavlink v2:

function parsePacket(buffer: Uint8Array): MavlinkMessage | null {
  if (buffer[0] !== 0xfd) return null; // v2 magic byte

  const len = buffer[1];
  const seq = buffer[2];
  const sys = buffer[3];
  const comp = buffer[4];
  const msgid = readUint32(buffer, 5);

  return decodeMessage(msgid, payload);
}

mavlink-browser on npm. ~15kb gzipped, tree-shakeable, works everywhere.

results

  • 500+ msg/sec on midrange laptops
  • zero allocs during steady-state
  • handles dialect switches mid-stream
  • 100% success on 2hr flight logs

~50 weekly downloads. drone dashboards + robotics startups.

real-world usage

used this at work in the worlds ivue app. check it out! works with WebSerial for plug-and-play USB radios. same parser handles websocket streams from the cloud and direct USB serial.

plug in a SiK radio, hit "connect", done. no drivers, no native apps.

the real win: live telemetry with zero backend. usb → webserial → parse → react all client side.

if you're building browser-based drone UIs, this is what you want. if not, then uh idk :)