Access USB Devices on the Web

The WebUSB API makes USB safer and easier to use by bringing it to the Web.

François Beaufort
François Beaufort

If I said plainly and simply "USB", there is a good chance that you will immediately think of keyboards, mice, audio, video, and storage devices. You're right, but you'll find other kinds of Universal Serial Bus (USB) devices out there.

These non-standardized USB devices require hardware vendors to write platform-specific drivers and SDKs in order for you (the developer) to take advantage of them. Sadly this platform-specific code has historically prevented these devices from being used by the Web. And that's one of the reasons the WebUSB API has been created: to provide a way to expose USB device services to the Web. With this API, hardware manufacturers will be able to build cross-platform JavaScript SDKs for their devices.

But most importantly this will make USB safer and easier to use by bringing it to the Web.

Let's see the behavior you could expect with the WebUSB API:

  1. Buy a USB device.
  2. Plug it into your computer. A notification appears right away, with the right website to go to for this device.
  3. Click the notification. The website is there and ready to use!
  4. Click to connect and a USB device chooser shows up in Chrome where you can pick your device.

Tada!

What would this procedure be like without the WebUSB API?

  1. Install a platform-specific application.
  2. If it's even supported on my operating system, verify that I've downloaded the right thing.
  3. Install the thing. If you're lucky, you'll get no scary OS prompts or popups warning you about installing drivers/applications from the internet. If you're unlucky, the installed drivers or applications malfunction and harm your computer. (Remember, the web is built to contain malfunctioning websites).
  4. If you only use the feature once, the code stays on your computer until you think to remove it. (On the Web, the space for unused is eventually reclaimed.)

Before I start

This article assumes you have some basic knowledge of how USB works. If not, I recommend reading USB in a NutShell. For background information about USB, check out the official USB specifications.

The WebUSB API is available in Chrome 61.

Available for origin trials

In order to get as much feedback as possible from developers using the WebUSB API in the field, we've previously added this feature in Chrome 54 and Chrome 57 as an origin trial.

The latest trial has successfully ended in September 2017.

Privacy and security

HTTPS only

Because of this feature's power, it only works on secure contexts. This means you'll need to build with TLS in mind.

User gesture required

As a security precaution, navigator.usb.requestDevice() may only be called through a user gesture such as a touch or mouse click.

Permissions Policy

A Permissions Policy is a mechanism that allows developers to selectively enable and disable various browser features and APIs. It can be defined via an HTTP header and/or an iframe "allow" attribute.

You can define a Permissions Policy that controls whether the usb attribute is exposed on the Navigator object, or in other words if you allow WebUSB.

Below is an example of a header policy where WebUSB is not allowed:

Feature-Policy: fullscreen "*"; usb "none"; payment "self" https://payment.example.com

Below is another example of a container policy where USB is allowed:

<iframe allowpaymentrequest allow="usb; fullscreen"></iframe>

Let's start coding

The WebUSB API relies heavily on JavaScript Promises. If you're not familiar with them, check out this great Promises tutorial. One more thing, () => {} are simply ECMAScript 2015 Arrow functions.

Get access to USB devices

You can either prompt the user to select a single connected USB device using navigator.usb.requestDevice() or call navigator.usb.getDevices() to get a list of all connected USB devices the website has been granted access to.

The navigator.usb.requestDevice() function takes a mandatory JavaScript object that defines filters. These filters are used to match any USB device with the given vendor (vendorId) and, optionally, product (productId) identifiers. The classCode, protocolCode, serialNumber, and subclassCode keys can also be defined there as well.