use-usb
Talk to USB devices with the WebUSB API.
| Package | @vizejs/composable/use-usb |
| Own the source | vize lib pull composable:use-usb |
| Runtime exports | useUSB |
| Gzip budget | 2304 B |
Minimal setup
Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).
vp install @vizejs/composable
Import the entry directly. Call lifecycle-bound utilities inside <script setup> so cleanup follows the component scope; consult the runtime contract for this entry's SSR and hydration behavior.
import { useUSB } from "@vizejs/composable/use-usb";
Try it
Grant access to a USB device
Let the reader choose a USB device such as a label printer and list the devices already allowed.
What to observe: Choose a USB device opens the chooser where WebUSB exists; previously allowed devices appear without asking again.
selectConfiguration, claimInterface and transfers are available after open. Every example renders a neutral message until it mounts, so server and client markup match, and then explains what to do when the browser lacks the API.
Compare the initial and interacted states


Copy the example
Save this complete SFC in your Vue project. Its public imports and source are the same ones executed in the preview.
<script setup lang="ts">
import { useMounted } from "@vizejs/composable/use-mounted";
import { useUSB } from "@vizejs/composable/use-usb";
const mounted = useMounted();
const { supported, devices, requestDevice } = useUSB();
</script>
<template>
<div class="composable-example">
<p>Let the reader grant access to a USB device, such as a label printer.</p>
<button type="button" :disabled="!mounted || !supported" @click="() => requestDevice([])">
Choose a USB device
</button>
<ul aria-label="Allowed devices">
<li v-for="item in devices" :key="`${item.vendorId}-${item.productId}`">
{{ item.productName }}
</li>
</ul>
<output aria-live="polite">{{
!mounted
? "Checking browser support…"
: supported
? `${devices.length} devices allowed.`
: "WebUSB is not available in this browser."
}}</output>
</div>
</template>
Runtime contract
| Utility | Category | Stability | SSR | Hydration | Cleanup | Targets | Host globals | Uses |
|---|---|---|---|---|---|---|---|---|
useUSB |
system | experimental | deterministic-fallback | caller-managed | reactive-scope, returned-value | web, desktop | window |
tryOnScopeDispose |
API
useUSB
Talk to USB devices with the WebUSB API. devices lists granted devices as plain snapshots and follows the host's connect / disconnect events. The device actions are thin wrappers over USBDevice that resolve to a boolean or the transfer result and record failures in error instead of rejecting. Host listeners are removed and sessions opened through open() are closed when the owning reactive scope stops; outside a scope call close() per device. Server rendering: supported is false and devices is empty.
function useUSB(options: UseUSBOptions = {}): USBControls
const usb = useUSB();
const device = await usb.requestDevice([{ vendorId: 0x2341 }]);
if (device && (await usb.open(device))) await usb.claimInterface(device, 0);
Types
USBDeviceFilter
Device filter for requestDevice.
| Member | Type | Description |
|---|---|---|
vendorId? |
number |
USB vendor id. |
productId? |
number |
USB product id. |
classCode? |
number |
Device or interface class code. |
subclassCode? |
number |
Device or interface subclass code. |
protocolCode? |
number |
Device or interface protocol code. |
serialNumber? |
string |
Serial number. |
USBInTransferResultLike
Result of an IN transfer.
| Member | Type | Description |
|---|---|---|
status |
USBTransferStatus |
Transfer status. |
data? |
DataView | null |
Received bytes. |
USBOutTransferResultLike
Result of an OUT transfer.
| Member | Type | Description |
|---|---|---|
status |
USBTransferStatus |
Transfer status. |
bytesWritten |
number |
Number of bytes written. |
USBControlTransferSetup
Setup packet of a control transfer.
| Member | Type | Description |
|---|---|---|
requestType |
"standard" | "class" | "vendor" |
Request category. |
recipient |
"device" | "interface" | "endpoint" | "other" |
Request target. |
request |
number |
bRequest. |
value |
number |
wValue. |
index |
number |
wIndex. |
USBDeviceLike
Minimal USBDevice used by useUSB.
| Member | Type | Description |
|---|---|---|
vendorId |
number |
USB vendor id. |
productId |
number |
USB product id. |
productName? |
string | undefined |
Product name. |
serialNumber? |
string | undefined |
Serial number. |
opened |
boolean |
Whether a session is open. |
open |
() => Promise<void> |
Start a session. |
close |
() => Promise<void> |
End the session. |
selectConfiguration |
(configurationValue: number) => Promise<void> |
Select a configuration by value. |
claimInterface |
(interfaceNumber: number) => Promise<void> |
Claim an interface. |
releaseInterface |
(interfaceNumber: number) => Promise<void> |
Release a claimed interface. |
transferIn |
(endpointNumber: number, length: number) => Promise<USBInTransferResultLike> |
Bulk/interrupt IN transfer. |
transferOut |
(endpointNumber: number, data: BufferSource) => Promise<USBOutTransferResultLike> |
Bulk/interrupt OUT transfer. |
controlTransferIn |
(setup: USBControlTransferSetup, length: number) => Promise<USBInTransferResultLike> |
Control IN transfer. |
controlTransferOut |
(setup: USBControlTransferSetup, data?: BufferSource) => Promise<USBOutTransferResultLike> |
Control OUT transfer. |
USBHost
navigator.usb-like capability used by useUSB.
| Member | Type | Description |
|---|---|---|
getDevices |
() => Promise<USBDeviceLike[]> |
Devices the page already has access to. |
requestDevice |
(options: { readonly filters: USBDeviceFilter[] }) => Promise<USBDeviceLike> |
Prompt the user for a device. |
USBDeviceInfo
Plain, reactive-friendly description of a granted device.
| Member | Type | Description |
|---|---|---|
device |
USBDeviceLike |
The live device, for passing back to the actions. |
vendorId |
number |
USB vendor id. |
productId |
number |
USB product id. |
productName |
string |
Product name (empty when unknown). |
serialNumber |
string |
Serial number (empty when unknown). |
opened |
boolean |
Whether a session was open when the list was refreshed. |
UseUSBOptions
Options for useUSB.
| Member | Type | Description |
|---|---|---|
host? |
MaybeRefOrGetter<USBHost | null | undefined> |
navigator.usb-like capability. |
USBControls
Reactive state and actions returned by useUSB.
| Member | Type | Description |
|---|---|---|
supported |
ComputedRef<boolean> |
Whether WebUSB is available. |
devices |
Readonly<ShallowRef<readonly USBDeviceInfo[]>> |
Granted devices, refreshed on connect / disconnect and after every action. |
error |
Readonly<ShallowRef<unknown>> |
Most recent failure. |
requestDevice |
(filters?: USBDeviceFilter[]) => Promise<USBDeviceLike | undefined> |
Prompt the user for a device (requires user activation). |
getDevices |
() => Promise<readonly USBDeviceInfo[]> |
Refresh devices. |
open |
(device: USBDeviceLike) => Promise<boolean> |
Open a session. |
close |
(device: USBDeviceLike) => Promise<boolean> |
Close a session. |
selectConfiguration |
(device: USBDeviceLike, value: number) => Promise<boolean> |
Select a configuration. |
claimInterface |
(device: USBDeviceLike, interfaceNumber: number) => Promise<boolean> |
Claim an interface. |
releaseInterface |
(device: USBDeviceLike, interfaceNumber: number) => Promise<boolean> |
Release an interface. |
transferIn |
( device: USBDeviceLike, endpoint: number, length: number, ) => Promise<USBInTransferResultLike | undefined> |
Bulk/interrupt IN transfer. |
transferOut |
( device: USBDeviceLike, endpoint: number, data: BufferSource, ) => Promise<USBOutTransferResultLike | undefined> |
Bulk/interrupt OUT transfer. |
controlTransferIn |
( device: USBDeviceLike, setup: USBControlTransferSetup, length: number, ) => Promise<USBInTransferResultLike | undefined> |
Control IN transfer. |
controlTransferOut |
( device: USBDeviceLike, setup: USBControlTransferSetup, data?: BufferSource, ) => Promise<USBOutTransferResultLike | undefined> |
Control OUT transfer. |