The WebHID API gives web pages direct access to Human Interface Devices — exotic gamepads, Nintendo Joy-Cons, Elgato Stream Decks, Jabra headsets, and custom HID peripherals. Unlike the Gamepad API, WebHID supports full bidirectional communication: reading input and sending output reports.
📌 What Is HID and WebHID?
HID (Human Interface Device) protocol is a standard for bi-directional communication between a host and peripherals. HID "reports" are structured byte arrays described by a "report descriptor." WebHID exposes this protocol to JavaScript, but blocks standard classes (keyboards, mice, FIDO keys) to prevent misuse.
🌐 Browser Support
| Browser | Support | Notes |
|---|---|---|
| Chrome 89+ | ✅ Full support | Desktop — Windows, Mac, Linux, ChromeOS |
| Edge 89+ | ✅ Full support | Chromium-based |
| Firefox | ❌ Not supported | Not on Firefox roadmap |
| Safari | ❌ Not supported | Apple has not implemented WebHID |
⚙️ The API — Input/Output/Feature Reports
if ('hid' in navigator) { /* supported */ }
// 1. Request device — user must click
const [device] = await navigator.hid.requestDevice({
filters: [{ vendorId: 0x057e, productId: 0x2007 }] // Joy-Con Right
});
await device.open();
// 2. Input reports — device → browser
device.addEventListener('inputreport', ({ data, reportId }) => {
if (reportId === 0x3f) {
const buttons = { 1:'A', 2:'X', 4:'B', 8:'Y' };
console.log('Button:', buttons[data.getUint8(0)]);
}
});
// 3. Output reports — browser → device (e.g. rumble)
await device.sendReport(0x01, new Uint8Array([1,0,1,64,64,0,1,64,64]));
// 4. Feature reports — bidirectional (e.g. LED blink)
await device.sendFeatureReport(1, Uint32Array.from([512, 0]));
const state = await device.receiveFeatureReport(1);
// 5. Revoke access
await device.forget(); // Chrome 100+🏢 Who Uses WebHID?
🎮 Exotic Gamepad Support
Nintendo Joy-Cons (gyro, rumble), DualSense adaptive triggers, controller features unavailable via standard Gamepad API.
🎛️ Elgato Stream Deck
Browser apps read button presses and write per-key LCD images directly — no Elgato software needed. Used in streaming tools and productivity dashboards.
🎤 Jabra/Poly Headsets
Browser-based UC apps (Teams, Zoom web) use WebHID for headset call control buttons — answer/mute/hang up from the physical device.
⌨️ X-keys & Accessibility
X-keys programmable keypads, accessibility switches, custom input hardware that need per-key feedback control.
📦 Open Source Projects
Official W3C WICG spec repository — issue tracker, explainers, and the living specification for WebHID.
Several open-source browser libraries for Stream Deck interaction (streamdeck-api, elgato-streamdeck) built on WebHID.
Browser tool for Joy-Con diagnostics: gyro/accel data, button mapping, vibration testing — entirely over WebHID.
Reference app that dumps full HID descriptor info in human-readable format — maps usage IDs to names for any connected HID device.
🔒 Security Model
- Standard classes blocked — keyboard (usage page 0x0001), FIDO (0xF1D0), generic mice blocked to prevent exploits
- User gesture + picker —
navigator.hid.requestDevice()requires click; browser shows device selector - HTTPS required — secure contexts only (localhost allowed for dev)
- Exclusion filters — sites can exclude malfunctioning devices from the picker via
exclusionFilters - Revocable —
device.forget()(Chrome 100+) or via chrome://settings/content/hidDevices
Written by Alex R. | Coding with Alex | Tags: WebHID, Browser APIs, Gamepad, Stream Deck, HID, Chrome