WebUSB API
Published
WebUSB API — The WebUSB API lets a web app request access to non-standard USB devices via navigator.usb.requestDevice() and communicate with them directly.
Browser & ecosystem support
Section titled “Browser & ecosystem support”- Legend
- Yes
- Partial
- Flag
- No
- Unknown
| Browser / Platform | Support | Versions | Confidence | Source | Notes |
|---|---|---|---|---|---|
| Chrome (Desktop) | Yes | 61 | high | source | — |
| Chrome (Android) | Yes | 61 | high | source | 1 |
| Edge (Desktop) | Yes | 79 | high | source | 2 |
| Firefox (Desktop) | No | — | high | source | 3 |
| Firefox (Android) | No | — | high | source | 45 |
| Safari (macOS) | No | — | high | source | 6 |
| Safari (iOS) | No | — | high | source | 78 |
| Samsung Internet | Yes | 8.0 | high | source | 9 |
| WebView (Android) | No | — | high | source | 10 |
| Opera | Yes | 48 | high | source | — |
- Derived by browser-compat-data mirroring from Chrome.
- Derived by browser-compat-data mirroring from Chrome.
- No Firefox support is recorded in browser-compat-data.
- No Firefox for Android support is recorded in browser-compat-data.
- Derived by browser-compat-data mirroring from Firefox.
- No Safari support is recorded in browser-compat-data.
- No Safari on iOS support is recorded in browser-compat-data.
- Derived by browser-compat-data mirroring from Safari.
- Derived by browser-compat-data mirroring from Chrome Android.
- No WebView Android support is recorded in browser-compat-data.
How to use it
Section titled “How to use it”Requesting a device must happen inside a user gesture, and filters narrows the picker to
devices matching a vendor/product ID pair. Once the user selects a device, open it before
transferring data:
async function connectUsbDevice() { const device = await navigator.usb.requestDevice({ filters: [{ vendorId: 0x1209, productId: 0xa800 }], }); await device.open(); return device;}The configuration and interface numbers to select and claim next are specific to each
device’s own descriptors — read them from device.configurations rather than assuming
fixed numbers, then call device.selectConfiguration() and device.claimInterface()
with the values found there.
How to detect it at runtime
Section titled “How to detect it at runtime”Check for navigator.usb before offering the feature, and give the reader a fallback path
when it is absent:
if ('usb' in navigator) { connectButton.hidden = false;} else { connectButton.hidden = true; fallbackNotice.textContent = 'This browser cannot access USB devices from the page.';}Practical checklist
Section titled “Practical checklist”- Requires a secure context (HTTPS) — it is unavailable on plain HTTP origins.
requestDevice()needs transient user activation (a click or keypress handler); without it, the returned promise rejects with aSecurityErrorDOMException.claimInterface()claims a specific interface for exclusive use: only one execution context can hold a given interface at a time, and it must be released withreleaseInterface()(or the device closed) before another context can claim it.- The picker only lists devices matching the
filtersyou pass, so a request with no matching device leaves the user with nothing to select, which rejects the returned promise. - Firefox and Safari do not implement the API, so
'usb' in navigatorisfalsethere and any USB-dependent flow needs the fallback path above.
Where to go next
Section titled “Where to go next”For the full reference (device pairing, permission model, landing pages), see WebUSB API.
See also Web Bluetooth API for the equivalent flow over Bluetooth.
← Back to the Compatibility explorer.