Web Usb

Web USB targets device vendors, not web developers. When a USB device has no OS driver, Web USB lets a website communicate with it directly -- updating firmware, flashing software, or running the device without any native software installed.

June 12, 20263 min read5 / 6

When you plug in a keyboard, the OS driver kicks in automatically. The device is recognized, enumerated, and available. You never need to think about the USB protocol.

Web USB is for the device that the OS does not recognize.

Custom hardware without a registered driver. A 3D printer that arrived with no macOS software. A microcontroller in bootloader mode waiting for a firmware flash. Web USB lets a website communicate with these devices directly -- no driver, no native app.

Who This API Is For

The spec is explicit about this: Web USB targets device vendors, not general web developers.

If you are building a website, this API is probably not for you. If you are manufacturing a hardware device and want users to be able to update its firmware or configure it from a website without installing anything, this is the API that makes that possible.

Practical examples: Web Serial is for communicating with microcontrollers that already have a standard CDC serial interface. Web USB is for talking to a device at the raw USB protocol level -- endpoint by endpoint, transfer by transfer.

The Connection

JavaScript
// User picks the device const device = await navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341, productId: 0x8036 }] }) // Open the device and claim the interface await device.open() await device.selectConfiguration(1) await device.claimInterface(0)

vendorId and productId are USB identifiers assigned to the device by its manufacturer. You get them from the device documentation or by inspecting the USB descriptor. claimInterface is required before any data transfer -- the interface number comes from the device's configuration descriptor.

Reading and Writing

JavaScript
// Write data to the device const data = new Uint8Array([0x01, 0x02, 0x03]) await device.transferOut(2, data) // endpoint 2 out // Read data from the device const result = await device.transferIn(1, 64) // endpoint 1 in, 64 bytes max console.log(new Uint8Array(result.data.buffer))

transferOut sends bytes to an OUT endpoint. transferIn reads bytes from an IN endpoint. Endpoint numbers come from the device's USB descriptor.

All of this is binary. The byte format is device-specific. The endpoint numbers are device-specific. The protocol is device-specific. Nothing here is automatic -- you need the device's USB documentation to know what to send and what to expect.

Web USB: standard USB path with OS driver vs Web USB path without driver, and the four connection steps ExpandWeb USB: standard USB path with OS driver vs Web USB path without driver, and the four connection steps

What It Replaces

Web USB exists to eliminate the install-our-app-first pattern for hardware setup. The original audience was developers building tools like:

  • Firmware flashers for microcontrollers (update your device firmware from a website)
  • Device configurators for custom hardware
  • Driver-free access to devices on Chromebooks, where a full driver ecosystem may not exist

The Chrome team's original vision was partly shaped by Chromebook's constraints. Chromebooks run Chrome OS, and for certain hardware use cases, a web-based tool that talks USB directly was more practical than maintaining native drivers.

Support

Web USB is light-green tier. Chromium-based browsers (Chrome, Edge) support it. Firefox and Safari do not.

JavaScript
if ('usb' in navigator) { // Web USB is available }

The last external-device API in this chapter communicates over radio waves rather than a wire. Web NFC reads and writes passive tags at close range -- no pairing, no connection, just tap.

The Essentials

  1. Web USB targets device vendors building custom hardware -- not regular web developers. If you are writing a web app, you probably need Web Serial instead.
  2. The device must have no OS driver registered for Web USB to be the right path. If the OS claims the device through a driver, Web USB cannot access it.
  3. Connection flow: requestDevice()open()selectConfiguration(1)claimInterface(n)transferIn / transferOut.
  4. All communication is binary data on specific USB endpoints. Endpoint numbers and data formats come from the device's USB descriptor.
  5. Chromium only. No plans from Firefox or Safari.

Further Reading and Watching