awawausb-webusb-firefox

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

awawausb — WebUSB Extension for Firefox

awawausb — 适用于Firefox的WebUSB扩展

Skill by ara.so — Daily 2026 Skills collection.
awawausb
adds WebUSB (
navigator.usb
) to Firefox via a two-part system: a browser extension (
.xpi
) and a native stub binary (compiled Rust) that communicates over native messaging.
ara.so提供的技能 — 2026每日技能合集。
awawausb
通过一套双组件系统为Firefox添加WebUSB(
navigator.usb
)功能:一个浏览器扩展(
.xpi
)和一个通过原生消息传递进行通信的原生存根二进制文件(基于Rust编译)。

Architecture

架构

Web Page (navigator.usb)
    ↕  WebExtension API
Firefox Extension (extension/)
    ↕  Native Messaging (stdio, JSON-framed)
Native Stub Binary (native-stub/ — Rust)
    ↕  OS USB APIs (WinUSB / libusb / IOKit)
USB Device
Web Page (navigator.usb)
    ↕  WebExtension API
Firefox Extension (extension/)
    ↕  Native Messaging (stdio, JSON-framed)
Native Stub Binary (native-stub/ — Rust)
    ↕  OS USB APIs (WinUSB / libusb / IOKit)
USB Device

Installation (End Users)

安装(终端用户)

1. Install the Extension

1. 安装扩展

  • Signed release: Download
    .xpi
    from GitHub Releases, open in Firefox.
  • Developer/testing:
    about:debugging
    → "This Firefox" → "Load Temporary Add-on…" → select
    extension/manifest.json
    .
  • 签名版本:从GitHub Releases下载
    .xpi
    文件,在Firefox中打开。
  • 开发者/测试版本:打开
    about:debugging
    → "此Firefox" → "加载临时附加组件…" → 选择
    extension/manifest.json

2. Install the Native Stub

2. 安装原生存根

Download and unzip the release archive for your platform, then run:
bash
undefined
下载对应平台的发布压缩包并解压,然后运行:
bash
undefined

Linux / macOS

Linux / macOS

./install.sh
./install.sh

Windows

Windows

install.bat

Supported platforms: macOS x86_64/ARM64, Linux x86_64/aarch64, Windows AMD64/ARM64.
install.bat

支持的平台:macOS x86_64/ARM64、Linux x86_64/aarch64、Windows AMD64/ARM64。

Building from Source

从源码构建

bash
undefined
bash
undefined

Clone

克隆仓库

git clone https://github.com/ArcaneNibble/awawausb cd awawausb/native-stub
git clone https://github.com/ArcaneNibble/awawausb cd awawausb/native-stub

Default build (host platform)

默认构建(主机平台)

cargo build --release
undefined
cargo build --release
undefined

Platform Notes

平台说明

PlatformNotes
macOSShould "just work"; vendored
.tbd
files included
LinuxUses musl libc by default for static binaries; glibc builds work but untested
WindowsUses mingw-w64 UCRT (
*-windows-gnullvm
); MSVC not supported
平台说明
macOS应可“直接运行”;已包含预编译的
.tbd
文件
Linux默认使用musl libc生成静态二进制文件;glibc构建可用但未测试
Windows使用mingw-w64 UCRT(
*-windows-gnullvm
);不支持MSVC

Cross-compiling (Linux → Windows example)

交叉编译(Linux → Windows示例)

bash
undefined
bash
undefined

Install mingw-w64, then:

安装mingw-w64,然后执行:

rustup target add x86_64-pc-windows-gnullvm cargo build --release --target x86_64-pc-windows-gnullvm
undefined
rustup target add x86_64-pc-windows-gnullvm cargo build --release --target x86_64-pc-windows-gnullvm
undefined

Manual Native Manifest Setup

手动设置原生清单

After building, tell Firefox where the native stub binary is by placing a JSON manifest file in the correct location.
构建完成后,通过将JSON清单文件放置在正确位置,告知Firefox原生存根二进制文件的路径。

Manifest Content

清单内容

json
{
  "name": "awawausb_native_stub",
  "description": "Allows WebUSB extension to access USB devices",
  "path": "/absolute/path/to/awawausb-native-stub",
  "type": "stdio",
  "allowed_extensions": ["awawausb@arcanenibble.com"]
}
On Windows,
path
can be just
"awawausb-native-stub.exe"
(no absolute path required).
json
{
  "name": "awawausb_native_stub",
  "description": "Allows WebUSB extension to access USB devices",
  "path": "/absolute/path/to/awawausb-native-stub",
  "type": "stdio",
  "allowed_extensions": ["awawausb@arcanenibble.com"]
}
在Windows系统中,
path
可以仅填写
"awawausb-native-stub.exe"
(无需绝对路径)。

Manifest Locations

清单位置

macOS
undefined
macOS
undefined

Global

全局

/Library/Application Support/Mozilla/NativeMessagingHosts/awawausb_native_stub.json
/Library/Application Support/Mozilla/NativeMessagingHosts/awawausb_native_stub.json

User-local

用户本地

~/Library/Application Support/Mozilla/NativeMessagingHosts/awawausb_native_stub.json

**Linux**
~/Library/Application Support/Mozilla/NativeMessagingHosts/awawausb_native_stub.json

**Linux**

Global

全局

/usr/lib/mozilla/native-messaging-hosts/awawausb_native_stub.json /usr/lib64/mozilla/native-messaging-hosts/awawausb_native_stub.json
/usr/lib/mozilla/native-messaging-hosts/awawausb_native_stub.json /usr/lib64/mozilla/native-messaging-hosts/awawausb_native_stub.json

User-local

用户本地

~/.mozilla/native-messaging-hosts/awawausb_native_stub.json

**Windows** (registry keys)
~/.mozilla/native-messaging-hosts/awawausb_native_stub.json

**Windows**(注册表项)

Global

全局

HKLM\SOFTWARE\Mozilla\NativeMessagingHosts\awawausb_native_stub
HKLM\SOFTWARE\Mozilla\NativeMessagingHosts\awawausb_native_stub

User-local

用户本地

HKCU\SOFTWARE\Mozilla\NativeMessagingHosts\awawausb_native_stub

The registry value should be the full path to the manifest `.json` file.
HKCU\SOFTWARE\Mozilla\NativeMessagingHosts\awawausb_native_stub

注册表值应为清单`.json`文件的完整路径。

Quick Linux user-local setup script

Linux用户本地快速设置脚本

bash
#!/usr/bin/env bash
STUB_PATH="$(pwd)/native-stub/target/release/awawausb-native-stub"
MANIFEST_DIR="$HOME/.mozilla/native-messaging-hosts"
mkdir -p "$MANIFEST_DIR"

cat > "$MANIFEST_DIR/awawausb_native_stub.json" <<EOF
{
  "name": "awawausb_native_stub",
  "description": "Allows WebUSB extension to access USB devices",
  "path": "$STUB_PATH",
  "type": "stdio",
  "allowed_extensions": ["awawausb@arcanenibble.com"]
}
EOF

echo "Native manifest written to $MANIFEST_DIR/awawausb_native_stub.json"
bash
#!/usr/bin/env bash
STUB_PATH="$(pwd)/native-stub/target/release/awawausb-native-stub"
MANIFEST_DIR="$HOME/.mozilla/native-messaging-hosts"
mkdir -p "$MANIFEST_DIR"

cat > "$MANIFEST_DIR/awawausb_native_stub.json" <<EOF
{
  "name": "awawausb_native_stub",
  "description": "Allows WebUSB extension to access USB devices",
  "path": "$STUB_PATH",
  "type": "stdio",
  "allowed_extensions": ["awawausb@arcanenibble.com"]
}
EOF

echo "Native manifest written to $MANIFEST_DIR/awawausb_native_stub.json"

Quick macOS user-local setup

macOS用户本地快速设置

bash
#!/usr/bin/env bash
STUB_PATH="$(pwd)/native-stub/target/release/awawausb-native-stub"
MANIFEST_DIR="$HOME/Library/Application Support/Mozilla/NativeMessagingHosts"
mkdir -p "$MANIFEST_DIR"

cat > "$MANIFEST_DIR/awawausb_native_stub.json" <<EOF
{
  "name": "awawausb_native_stub",
  "description": "Allows WebUSB extension to access USB devices",
  "path": "$STUB_PATH",
  "type": "stdio",
  "allowed_extensions": ["awawausb@arcanenibble.com"]
}
EOF
bash
#!/usr/bin/env bash
STUB_PATH="$(pwd)/native-stub/target/release/awawausb-native-stub"
MANIFEST_DIR="$HOME/Library/Application Support/Mozilla/NativeMessagingHosts"
mkdir -p "$MANIFEST_DIR"

cat > "$MANIFEST_DIR/awawausb_native_stub.json" <<EOF
{
  "name": "awawausb_native_stub",
  "description": "Allows WebUSB extension to access USB devices",
  "path": "$STUB_PATH",
  "type": "stdio",
  "allowed_extensions": ["awawausb@arcanenibble.com"]
}
EOF

Windows PowerShell setup

Windows PowerShell设置

powershell
$stubPath = "C:\path\to\awawausb-native-stub.exe"
$manifestPath = "C:\ProgramData\Mozilla\awawausb_native_stub.json"

$manifest = @{
    name = "awawausb_native_stub"
    description = "Allows WebUSB extension to access USB devices"
    path = $stubPath
    type = "stdio"
    allowed_extensions = @("awawausb@arcanenibble.com")
} | ConvertTo-Json

Set-Content -Path $manifestPath -Value $manifest
powershell
$stubPath = "C:\path\to\awawausb-native-stub.exe"
$manifestPath = "C:\ProgramData\Mozilla\awawausb_native_stub.json"

$manifest = @{
    name = "awawausb_native_stub"
    description = "Allows WebUSB extension to access USB devices"
    path = $stubPath
    type = "stdio"
    allowed_extensions = @("awawausb@arcanenibble.com")
} | ConvertTo-Json

Set-Content -Path $manifestPath -Value $manifest

Register for current user

为当前用户注册

New-Item -Path "HKCU:\SOFTWARE\Mozilla\NativeMessagingHosts\awawausb_native_stub" -Force Set-ItemProperty -Path "HKCU:\SOFTWARE\Mozilla\NativeMessagingHosts\awawausb_native_stub" ` -Name "(Default)" -Value $manifestPath
undefined
New-Item -Path "HKCU:\SOFTWARE\Mozilla\NativeMessagingHosts\awawausb_native_stub" -Force Set-ItemProperty -Path "HKCU:\SOFTWARE\Mozilla\NativeMessagingHosts\awawausb_native_stub" ` -Name "(Default)" -Value $manifestPath
undefined

Using WebUSB in Web Pages

在网页中使用WebUSB

Once installed,
navigator.usb
is available. Usage is identical to Chrome's WebUSB API:
javascript
// Request a device (requires user gesture)
async function connectDevice() {
  try {
    const device = await navigator.usb.requestDevice({
      filters: [
        { vendorId: 0x1234 },                          // by vendor
        { vendorId: 0x5678, productId: 0x9abc },       // by vendor+product
        { classCode: 0xff }                             // by class
      ]
    });

    await device.open();
    await device.selectConfiguration(1);
    await device.claimInterface(0);

    // Send data
    const data = new Uint8Array([0x01, 0x02, 0x03]);
    await device.transferOut(1, data);

    // Receive data
    const result = await device.transferIn(1, 64);
    console.log('Received:', new Uint8Array(result.data.buffer));

    await device.close();
  } catch (err) {
    console.error('USB error:', err);
  }
}

// List previously-authorized devices
async function listDevices() {
  const devices = await navigator.usb.getDevices();
  devices.forEach(d => {
    console.log(`${d.manufacturerName} ${d.productName} (${d.vendorId}:${d.productId})`);
  });
}

// Watch for connect/disconnect
navigator.usb.addEventListener('connect', e => {
  console.log('Device connected:', e.device);
});
navigator.usb.addEventListener('disconnect', e => {
  console.log('Device disconnected:', e.device);
});
Note: The WebUSB API is only available on the main page — not in Web Workers.
安装完成后,
navigator.usb
即可使用。使用方式与Chrome的WebUSB API完全一致:
javascript
// 请求设备(需要用户交互)
async function connectDevice() {
  try {
    const device = await navigator.usb.requestDevice({
      filters: [
        { vendorId: 0x1234 },                          // 按厂商ID筛选
        { vendorId: 0x5678, productId: 0x9abc },       // 按厂商ID+产品ID筛选
        { classCode: 0xff }                             // 按设备类别筛选
      ]
    });

    await device.open();
    await device.selectConfiguration(1);
    await device.claimInterface(0);

    // 发送数据
    const data = new Uint8Array([0x01, 0x02, 0x03]);
    await device.transferOut(1, data);

    // 接收数据
    const result = await device.transferIn(1, 64);
    console.log('Received:', new Uint8Array(result.data.buffer));

    await device.close();
  } catch (err) {
    console.error('USB error:', err);
  }
}

// 列出已授权的设备
async function listDevices() {
  const devices = await navigator.usb.getDevices();
  devices.forEach(d => {
    console.log(`${d.manufacturerName} ${d.productName} (${d.vendorId}:${d.productId})`);
  });
}

// 监听设备连接/断开事件
navigator.usb.addEventListener('connect', e => {
  console.log('Device connected:', e.device);
});
navigator.usb.addEventListener('disconnect', e => {
  console.log('Device disconnected:', e.device);
});
注意:WebUSB API仅在主页面可用,无法在Web Workers中使用。

System Requirements

系统要求

OSRequirement
macOS10.15+; macOS 12 recommended
WindowsWindows 10+ (WinUSB driver required for target device)
LinuxKernel 4.8+; udev daemon;
/dev
and
/sys
mounted
操作系统要求
macOS10.15+;推荐使用macOS 12
WindowsWindows 10+(目标设备需WinUSB驱动)
Linux内核4.8+;udev守护进程;已挂载
/dev
/sys

Linux udev Rules (if device access is denied)

Linux udev规则(若设备访问被拒绝)

undefined
undefined

/etc/udev/rules.d/99-webusb.rules

/etc/udev/rules.d/99-webusb.rules

SUBSYSTEM=="usb", ATTR{idVendor}=="1234", ATTR{idProduct}=="5678", MODE="0666", GROUP="plugdev"

```bash
sudo udevadm control --reload-rules
sudo udevadm trigger
SUBSYSTEM=="usb", ATTR{idVendor}=="1234", ATTR{idProduct}=="5678", MODE="0666", GROUP="plugdev"

```bash
sudo udevadm control --reload-rules
sudo udevadm trigger

Windows: Switching to WinUSB Driver

Windows:切换到WinUSB驱动

If a device isn't listed, it may not use WinUSB. Use Zadig:
  1. Open Zadig, select the device
  2. Choose "WinUSB" as the driver
  3. Click "Replace Driver"
⚠️ Switching to WinUSB removes the device from other Windows subsystems (e.g., a printer will no longer appear as a printer).
若设备未被列出,可能是因为未使用WinUSB驱动。使用Zadig工具:
  1. 打开Zadig,选择目标设备
  2. 选择“WinUSB”作为驱动
  3. 点击“Replace Driver”(替换驱动)
⚠️ 切换到WinUSB驱动会使设备脱离其他Windows子系统(例如,打印机将不再显示为打印机)。

Troubleshooting

故障排查

Check Extension Debugging Page

检查扩展调试页面

Click the awawausb toolbar button (under the Extensions icon) → use "List devices" to see all USB devices the extension can see.
  • Device listed but page can't use it → likely a permissions/origin issue in the web page.
  • Device NOT listed → OS-level configuration problem (driver, udev rules, permissions).
点击awawausb工具栏按钮(在扩展图标下)→ 使用“List devices”(列出设备)查看扩展能识别的所有USB设备。
  • 设备已列出但网页无法使用 → 可能是网页存在权限或来源问题。
  • 设备未列出 → 存在操作系统层面的配置问题(驱动、udev规则、权限)。

Native Stub Not Found

原生存根未找到

Symptoms: extension toolbar shows an error; no devices listed.
  1. Verify the manifest file exists at the correct path for your OS.
  2. Verify
    "path"
    in the manifest points to the actual binary.
  3. Verify the binary is executable:
    chmod +x /path/to/awawausb-native-stub
  4. Check Firefox's browser console (
    about:debugging
    → inspect extension) for native messaging errors.
症状:扩展工具栏显示错误;无设备列出。
  1. 验证清单文件是否存在于对应操作系统的正确路径。
  2. 验证清单中的
    "path"
    指向实际的二进制文件。
  3. 验证二进制文件具有可执行权限:
    chmod +x /path/to/awawausb-native-stub
  4. 查看Firefox的浏览器控制台(
    about:debugging
    → 检查扩展)中的原生消息传递错误。

Linux: Device Not Detected

Linux:设备未被检测到

bash
undefined
bash
undefined

Verify udev is running and broadcasting on NETLINK_KOBJECT_UEVENT group 2

验证udev是否在运行,并在NETLINK_KOBJECT_UEVENT组2上广播

udevadm monitor --udev --subsystem-match=usb
udevadm monitor --udev --subsystem-match=usb

Check kernel version

检查内核版本

uname -r # must be >= 4.8
undefined
uname -r # 必须 >= 4.8
undefined

Build Fails on Linux (musl)

Linux上构建失败(musl)

bash
undefined
bash
undefined

Install musl target

安装musl目标

rustup target add x86_64-unknown-linux-musl
rustup target add x86_64-unknown-linux-musl

Install musl toolchain (Debian/Ubuntu)

安装musl工具链(Debian/Ubuntu)

sudo apt install musl-tools cargo build --release --target x86_64-unknown-linux-musl
undefined
sudo apt install musl-tools cargo build --release --target x86_64-unknown-linux-musl
undefined

Shared Home Directory / Roaming Profiles

共享主目录/漫游配置文件

The native manifest uses absolute paths, which breaks when the same home directory is used across machines with different CPU architectures. Workarounds:
  • Use a wrapper script at a fixed path that
    exec
    s the correct binary based on
    uname -m
    .
  • Use separate per-machine manifest directories if your OS supports it.
原生清单使用绝对路径,当同一主目录在不同CPU架构的机器上使用时会失效。解决方法:
  • 在固定路径使用包装脚本,根据
    uname -m
    执行正确的二进制文件。
  • 如果操作系统支持,使用独立的每台机器清单目录。

Known Limitations

已知限制

  • No Web Worker support (API only on main page).
  • No Android support (no native messaging on Android Firefox).
  • Windows requires WinUSB driver on target device.
  • Linux requires udev-compatible daemon for hotplug detection.
  • 不支持Web Worker(API仅在主页面可用)。
  • 不支持Android(Android版Firefox无原生消息传递功能)。
  • Windows系统要求目标设备使用WinUSB驱动。
  • Linux系统需要兼容udev的守护进程以支持热插拔检测。