Detecting…
1 Connect
The controller must be wired, not Bluetooth.
Not connected.
Rumble test
Optional. Uses the Gamepad API, not WebUSB, so it works while
xpad owns the controller. Press a button on the pad first if it
is not listed.
Press a button on the controller, then test.
Before you start
Use a data cable and keep it connected. The controller restarts five times during a full update and re-enumerates on USB. Do not unplug it, close the tab or put the machine to sleep while the progress bar is moving. If an update stops halfway, plug the controller back in and run it again; it resumes with the components that still differ.
Open the controller and release it from xpad
Two separate things: the udev rule lets your user open the USB device node, and the unbind releases interface 0 from the kernel driver. Browsers do not detach kernel drivers, so Linux needs both.
Linux
-
Allow your user to open the controller's USB device node, then replug the
controller. This rule lives in
/rununtil reboot, so it also works on NixOS and systems with a read-only/etc:sudo install -d /run/udev/rules.d echo 'SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{bDeviceClass}=="ff", ATTR{bDeviceSubClass}=="47", ATTR{bDeviceProtocol}=="d0", TAG+="uaccess"' \ | sudo tee /run/udev/rules.d/70-xbox-webusb.rules sudo udevadm control --reload-rules sudo udevadm trigger --action=add --subsystem-match=usb -
Find the interface name and release it from
xpad:ls -l /sys/bus/usb/drivers/xpad/ # e.g. 5-3:1.0 echo -n '5-3:1.0' | sudo tee /sys/bus/usb/drivers/xpad/unbind
If the controller is bound to a different driver (for examplexpadneo), use that driver's directory instead. -
After the update, unplug and replug the controller, or bind it back:
echo -n '5-3:1.0' | sudo tee /sys/bus/usb/drivers/xpad/bind
NixOS: do not use services.udev.extraRules for this; it becomes
99-local.rules, which is too late for the uaccess
builtin. Install the same rule with services.udev.packages and
destination = "/etc/udev/rules.d/70-xbox-webusb.rules". The
/run rule above works without a rebuild.
Windows
-
WebUSB needs WinUSB on the controller. With
Zadig: Options → List All Devices,
select Controller (USB ID
045E:0B12), choose WinUSB and Replace Driver. - This replaces the stock Xbox driver, so the pad stops working as a gamepad until you restore it: Device Manager → the controller → Uninstall device (tick Delete the driver software), then replug.
- The Xbox Accessories app cannot update the controller while WinUSB is bound. Use this page, or restore the stock driver first.
macOS
Not supported: Apple's XboxUSBDevice driver holds the controller
exclusively and there is no supported way for a browser to take it over. Use the
native tool instead:
sudo xboxctl update --latest
(xboxctl).
ChromeOS / Android
No driver to release. Connect the controller with a data cable (USB-OTG on Android), press Connect and allow the device. Chrome on Android supports WebUSB; a desktop Chromium browser is still the better-tested path.
Other things that hold the controller open
Close Steam, xboxdrv, gamepad testers and any other tab that uses the
controller. Only one program can claim interface 0 at a time.
What this can and cannot do
- It flashes official, signed Microsoft firmware. The controller verifies the signature; custom firmware is not possible.
- The bootloader (component 1) is never written, so a failed update can normally be recovered by reconnecting and retrying.
- Firmware updates are USB-only. Microsoft does not support updating over Bluetooth, and neither does this page.
Protocol implementation ported from xboxctl (0BSD). GIP transport is documented by Microsoft as MS-GIPUSB.