Web Serial API: How It Works, Who Uses It & Open Source Projects

Web Serial API thumbnail
馃摗

Web Serial API — Deep Dive

Talk to Microcontrollers, 3D Printers & More — Directly from Your Browser

Chrome / Edge (Desktop) Launched Chrome 89 USB & Bluetooth Serial Streams API

The Web Serial API allows websites to communicate with serial devices — microcontrollers, 3D printers, GPS receivers, oscilloscopes — connected via physical serial ports, USB-to-serial adapters, or Bluetooth serial emulation. Launched in Chrome 89, it is the successor to workarounds involving native helper apps or WebUSB serial emulation.

馃搶 What Is the Web Serial API?

Serial communication is one of the oldest and most widely-used protocols in computing. Almost every microcontroller (Arduino, ESP32, Raspberry Pi Pico, STM32, etc.) has a UART interface. The Web Serial API wraps the native OS serial port API and exposes it to JavaScript through the Streams API — making reads and writes asynchronous and composable.

Key distinction: Web Serial works with devices that expose a serial port to the OS (via CDC-ACM USB class or Bluetooth SPP) — not with raw USB endpoints. For raw USB access, use WebUSB. For HID devices, use WebHID.

馃寪 Browser Support

BrowserSupportNotes
Chrome 89+ (Desktop)✅ Full supportWindows, Mac, Linux, ChromeOS. Not Android (OS limitation).
Edge 89+ (Desktop)✅ Full supportChromium-based Edge, same as Chrome.
Firefox❌ Not supportedNot on Firefox roadmap. Position: not harmful but not prioritised.
Safari❌ Not supportedApple has not shipped Web Serial API.

⚙️ How It Works — The API

// Feature detection
if ('serial' in navigator) { /* supported */ }

// 1. Request a port — requires user gesture
const port = await navigator.serial.requestPort({
  filters: [{ usbVendorId: 0x2341 }]  // Arduino
});

// 2. Open at 9600 baud
await port.open({ baudRate: 9600 });

// 3. Read data using Streams API
const reader = port.readable.getReader();
while (true) {
  const { value, done } = await reader.read();
  if (done) { reader.releaseLock(); break; }
  console.log(new TextDecoder().decode(value));
}

// 4. Write data
const writer = port.writable.getWriter();
await writer.write(new TextEncoder().encode('hello
'));
writer.releaseLock();

// 5. Close the port
await port.close();

馃攢 Reading with Transform Streams

Serial data arrives in arbitrary chunks. Transform streams let you parse it into meaningful units:

// Parse incoming serial data line-by-line
const textDecoder = new TextDecoderStream();
port.readable.pipeTo(textDecoder.writable);
const reader = textDecoder.readable
  .pipeThrough(new TransformStream(new LineBreakTransformer()))
  .getReader();

class LineBreakTransformer {
  constructor() { this.chunks = ''; }
  transform(chunk, controller) {
    this.chunks += chunk;
    const lines = this.chunks.split('\r\n');
    this.chunks = lines.pop();
    lines.forEach(l => controller.enqueue(l));
  }
  flush(controller) { controller.enqueue(this.chunks); }
}

馃彚 Who Uses Web Serial?

ProjectUse CaseURL
Arduino Create / CloudSerial monitor for Arduino boards in browsercreate.arduino.cc
Betaflight ConfiguratorConfigure drone flight controllers over serialgithub.com/betaflight
Espruino Web IDEREPL and code upload to Espruino boardsespruino.com/ide
Microsoft MakeCodeSerial console for BBC micro:bit in browsermakecode.com
Octoprint (via WebSerial)3D printer control — send G-code, monitor tempsoctoprint.org
Serial Terminal (Chrome Demo)Reference implementation — full terminal emulatorgooglechromelabs.github.io/serial-terminal

馃摝 Open Source Tooling

WICG/serial

Official W3C WICG spec repository for the Web Serial API. Issue tracker and living specification.

Serial API polyfill

On Android, WebUSB + the Serial API polyfill provides USB-based serial port support as a fallback.

googlechromelabs/serial-terminal

Full-featured browser serial terminal — ANSI colors, line ending options, hex view. Great reference app.

nickvdyck/webserial-polyfill

WebUSB-based polyfill for Web Serial API — provides the navigator.serial interface on top of WebUSB.

馃敀 Security Model

  • User gesture requirednavigator.serial.requestPort() only callable from user interaction
  • Picker dialog — browser shows OS-level port list; site can filter by USB vendor/product ID
  • HTTPS required — only secure contexts (or localhost for development)
  • Permissions Policy — restrict serial access in iframes: <iframe allow="serial">
  • Revocable access — via port.forget() (Chrome 103+) or chrome://settings/content/serialPorts
  • One port at a time — each requestPort() grants access to one port only

Written by Alex R. | Coding with Alex | Tags: Web Serial, Browser APIs, Arduino, 3D Printers, Chrome, Serial Communication

Post a Comment

Previous Post Next Post