A partial archive of discourse.wicg.io as of Saturday February 24, 2024.

Human Interface Device (HID) API


A Human Interface Device (HID) is a type of device that takes input from or provides output to humans. It also refers to the HID protocol, a standard for bi-directional communication between a host and a device that is designed to simplify the installation procedure.

The web already supports input from HID devices. Keyboards, mice, touchscreens, and gamepads are all typically implemented using the HID protocol. However, this support relies on the operating system’s HID drivers to transform incoming HID reports into native input events. Devices that are not well supported by the generic HID driver are often inaccessible to web applications. Similarly, the outputs on most devices are also inaccessible.

This issue is particularly painful when it comes to HID gamepads. The HID standard defines many usages that are relevant for gamepads, but the mapping of these usages to physical button locations is inconsistent across manufacturers. As a result, it is almost always the case that some device-specific logic is needed. Native applications typically leave this device-specific logic to a dedicated library.

We propose an API for requesting access to HID devices using a chooser-based permission model similar to the one used for WebUSB and Web Bluetooth. The API would enable a web application to send output and feature reports to the device as well as listen for input reports. Direct access to devices using the HID protocol would allow the device-specific logic to move out of the user agent and into the application layer, enabling the use of more devices on the web and reducing the complexity of the user agent.

Please take a look at our WebHID explainer. The API is similar to the chrome.hid API and is intended to fill a similar niche.


Thanks for putting this proposal together, together with the comprehensive README.

Just making a few notes/reactions/reactions… this seems to have a similarity to Web MIDI - does it exhibit potentially the same security characteristics? (i.e., can messages be sent that could cause the HID device to be misused/hijacked).

There might be some relationship in design with the Web Serial API.

If the main use case is gamepads, could we continue to improve the GamePad API instead? Are there mainstream HID devices in common use where this API would bring significant value to users?


Yes, this API would have similar security characteristics to APIs like MIDI, USB, Bluetooth, and Serial that allow bidirectional communication with external devices. To mitigate the risk, we require that the device is selected from a chooser before any data can be sent or received. As an additional mitigation, we will block HID access to devices that generate trusted input events.

I would prefer to see more gamepads supported through the Gamepad API. However, the design of the API makes it difficult to support new devices as well as the long tail of less-popular devices. To support a device, the browser must be able to recognize the device’s input report format so it knows how to transform the button and axis data to match the Standard Gamepad layout. The work to add support for a device typically requires access to the device itself, relies on undocumented behavior, is difficult to test for regressions, and is unlikely to be undertaken by browser vendors for all but the most popular devices.

Some mainstream HID devices that could take advantage of WebHID:

Nintendo Switch Joy-Cons are Bluetooth HID devices and can be used on several OSes as Bluetooth gamepads. However, they typically need additional software to support the mode where two Joy-Cons are used together as one gamepad. Furthermore, Switch users are accustomed to a complex GUI-driven procedure for pairing and associating the gamepads which is not feasible to implement within the browser. Enabling the page to communicate HID directly to the devices would allow applications to provide their own association flow for unusual devices like these.

The Logitech Unifying receiver is a USB HID device that forwards input events from a wireless device but does not use the OS’s support for wireless protocols like Bluetooth. Once a wireless device is paired with the receiver, it generally does not require any device-specific logic beyond what is provided by the OS’s generic HID drivers. However, it does require some device-specific logic to initiate the pairing process. On most platforms this is provided by a native executable, but sometimes this is not possible. By enabling access to HID devices, the pairing app could be implemented as a web app. This is important on platforms like Chrome OS where the native app functionality may be difficult to access or unavailable.


Thanks Matt,

Indeed, at Logitech, our mice and keyboards leverage standard HID functionality for most user input operations, but also communicate through HID vendor collections for more advanced functionality (proprietary HID++ protocol).

We use HID++ v1 in our Unifying receiver (USB dongle with a proprietary 2.4 Ghz radio), most noticeably to pair wireless devices. Back in 2014 we shipped a pairing utility using chrome.hid.

HID++ v2 provides advanced device configuration and firmware update capability.

Please notice that HID++ is also used over USB (mostly gaming devices), Bluetooth classic (HID profile) and Bluetooth smart (HID over Gatt).

In the same way as for web-bluetooth and web-usb, leveraging standards and the power of the Web Platform is far better than shipping potentially flawed / platform-specific drivers.

A web API also provides way better (seamless) user experience than going through traditional software/driver installers.



Logitech, Inc.


Has support for concurrently-used special-purpose keyboards been considered, e.g. trading keypads?

These are commonly used alongside a normal full-size keyboard, and are used for quick access to regular/time-sensitive operations. The key codes they expose as far as I know are the same as the normal keyboard, so the listening application would need to use the source of the key event to determine what action to take.

From what I can see, these would not be served by either WebHID or the Keyboard API. You mention that WebHID is not intended for keyboards, and security concerns which I appreciate. The web Keyboard API assumes a single keyboard, and the keyboard lock feature is only usable in fullscreen mode. I see that WebUSB prohibits devices that expose an HID profile - this is how I came to find WebHID.


The input report for keys on a trading keypad would most likely be defined inside a top-level collection with usage GenericDesktop/Keyboard or GenericDesktop/Keypad, which will be considered protected usages. Reports defined in a top-level collection with a protected usage will not be accessible through WebHID. I would expect that the OS’s HID driver would pick up these keypads and make them accessible through the Keyboard API. It’s unfortunate that the KeyboardEvent API doesn’t provide an ID to identify the device a key event came from.

If the keypad exposes additional controls in a separate top-level collection with a non-protected usage, those controls would be accessible through WebHID.


Thanks for confirming.

I’ve created a new topic for this: Identify which of multiple keyboards an event came from


Hello, I tried hid api in canary on my mac. I could connect, send/receive commands to my concept2 ergometer. (Really cool!, this is enough to make it possible to make ergometer-space.org connect using usb) I have one problem, I do not receive any disconnect events. Where can I file bugs? There is not yet an hid component in de chromium bug tracker.


Connect/disconnect events aren’t implemented yet. Please file bugs against the Blink>HID component.




I started an awesome list: https://github.com/robatwilliams/awesome-webhid

In case anyone’s looking for reference information, devices list, ideas, etc.


Greetings, is there a way to automatically reconnect to a device you already connected to, without having to explicitly grant access to the same device again? In our use case, we have a website using the HID API to configure custom sensors which all appear as the same device via the HID protocol. We have several hundred of them and would like to sequentially configure them, without needing to confirm via the ‘requestDevice’-popup that we want to connect to the sensor for every single device.


is there a way to automatically reconnect to a device you already connected to, without having to explicitly grant access to the same device again?

Not yet, but the plan is to support persistent permissions before the API is default-enabled in Chrome stable. Relevant Chromium bug: https://crbug.com/958918


sendReport() fails with “Permission denied” when trying to send data to a custom HID microcontroller.

The device shows up in Windows like this: 72636362-2d207680-395f-11ea-8a77-6ea287627973 In “Devices & Printers” (middle section), it shows up as “Unspecified”.

I can imagine that “Input device” is the problem here, but since it’s a game controller, that seems like the correct category. Should my device lie so I can connect to it or is there an “official” way of doing it?


This is most likely due to the HID report descriptor. To protect against input logging, Chrome blocks all input, output, and feature reports contained in a HID collection that the OS would recognize as a keyboard or pointing device. To avoid this, move the game controller input reports to a new top-level HID collection with usage Generic Desktop / Game Pad (usage page 1, usage 5).


I have been spending my x-mas vacation with webHID and I absolutely love it.

I got most of it to work, and to be honest, I was happy over the new year, but then, all of a sudden a change was seen upon disconnect/reconnect of my device.

I can swear it used to work, but shortly into 2021, I am experiencing, that my device collection is one smaller than before disconnect.

It seems the telephony page (0x0B) dissapears…

Upon disconnect I have 3 collections, then upon reconnect I only have 2…

I am going out of my mind, and the only thing I can think of, if an updated Canary browser…

Please if anyone can take me out of my misery, I would be forever grateful…

navigator.hid.addEventListener('disconnect', ({device}) => {
        console.log(device.collections.length);//**output 3**

navigator.hid.addEventListener('connect', ({device}) => {
        console.log(device.collections.length);//**output ONLY 2**

Sounds like an implementation bug… can you file it on the Chromium bug repo? Please set the Components field to “Blink>HID”.

updated Canary browser

That’s probably it. I recently made some changes in the Windows backend that could result in behavior like you describe.