1 Connect
The controller must be wired, not Bluetooth.
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.
The browser could not take the controller over. Either your user cannot open the USB device node, or another driver owns interface 0. WebUSB cannot detach kernel drivers, so fix that first, then reconnect.
USB device
GIP / firmware
Update protocol (UFU)
Flash components
| ID | Version | Partition | Notes |
|---|
2 Firmware package
Current release from Microsoft's PC feed.Loaded package
| ID | Version | Size | Address | Kind |
|---|
3 Update
Read the plan before writing anything.| ID | Controller | Package | Action |
|---|
Log
1 Prepare the controller
GuliKit update mode is a small USB drive, not a WebUSB device.- Power the controller off.
- Connect it with a data USB cable.
- Hold APG (the double-square button) + A, then power the controller on.
-
A drive named
GuliKitappears. Keep the cable connected and do not unplug it during the update.
The browser cannot detect or open that drive on its own; you will pick its root (or download the file) in step 3. If you have not mounted it yet, you can still download and verify the firmware first.
2 Firmware
.bin and copy the extracted file to the root of
the GuliKit drive with your file manager.
Selected file
3 Copy to the drive
The file must be at the root of the GuliKit drive. Do not copy it from
inside a zip archive; this page writes the extracted .bin directly.
After the controller reboots, check the version in the
GuliKit Setup Tool.
Before you start
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.
Before you start
GuliKit appears.
Do not unplug the controller while the file is being copied or while the drive is
disappearing.
Find the right file
The page uses GuliKit's official KK3 Max/Pro release. The KK3 Max is
NS39; the KK3 Pro is NS38. The controller only accepts
the matching .bin at the root of its drive. Do not rename it, put it
in a folder, or copy the zip archive itself.
Settings are separate from firmware updates
The APG + A drive only accepts firmware. To change button mapping, turbo/auto-fire, vibration, dead zones or lighting, reconnect the controller in normal PC mode and open the GuliKit Setup Tool. It works over USB, Bluetooth or the KK3 Hyperlink 2.4G adapter on firmware V5.7 or newer.
What this page can and cannot do
- It downloads the official file and verifies its SHA-256 against the bundled feed before writing anything.
-
The browser cannot detect the
GuliKitdrive automatically. You choose its root in the file picker; the page then writes the.bin. - It cannot see the update progress or the controller's version after flashing. The drive disappearing and the controller powering off are the success signals.
-
If the File System Access API is unavailable, use the download fallback and copy
the extracted
.binto the drive with your file manager.
If the drive does not appear
- Start from a powered-off controller; the button combination has to be held while powering on, not after it has booted.
- Use a data cable and try a different USB port. Close the GuliKit Setup Tool and any file manager window that has the drive open.
-
On Windows the volume may be assigned a drive letter; on Linux/macOS it mounts by
its
GuliKitlabel. Pick that volume's root in the picker.
After the update
The controller powers off when it has finished. Unplug and reconnect it in normal PC mode, then check the version in the GuliKit Setup Tool. Official instructions and the manual download are on GuliKit's KK3 Max/Pro firmware page.