Skip to content

Devices

Supported today

DeviceKindLightingLEDsUSB (VID:PID, connection)File
Razer BlackWidow V4 Pro 75%keyboard81 keys + 18 underglow991532:02B3 wiredrazer-blackwidow-v4-pro-75.toml
Razer Basilisk V3 Promousescroll wheel, logo, strip ×11131532:00AA wired
1532:00AB dongle
razer-basilisk-v3-pro.toml
Razer Goliathus Chroma Extendedmousemat1 zone11532:0C02 wiredrazer-goliathus-chroma-extended.toml

Experimental

Set up from OpenRazer and OpenRGB data. Nobody has confirmed these on real hardware yet, so uncoil won't change settings stored on one (key remaps, DPI stages, polling rate, sleep timer) until a read-only check passes. Lighting works without it. If you have one, tell us whether it works: one report is enough to move it to the supported list.

DeviceKindLightingUSB (VID:PID, connection)File
Razer BlackWidow V3keyboard105 keys1532:024E wiredrazer-blackwidow-v3.toml
Razer BlackWidow V3 Prokeyboard109 keys1532:025A wired
1532:025C dongle
razer-blackwidow-v3-pro.toml
Razer BlackWidow V3 Tenkeylesskeyboard87 keys1532:0A24 wiredrazer-blackwidow-v3-tkl.toml
Razer BlackWidow V4keyboard114 keys + 18 underglow1532:0287 wiredrazer-blackwidow-v4.toml
Razer BlackWidow V4 75%keyboard81 keys + 18 underglow1532:02A5 wiredrazer-blackwidow-v4-75.toml
Razer BlackWidow V4 Prokeyboard114 keys + 18 underglow + 20 wrist rest1532:028D wiredrazer-blackwidow-v4-pro.toml
Razer BlackWidow V4 Xkeyboard110 keys1532:0293 wiredrazer-blackwidow-v4-x.toml
Razer Huntsman Minikeyboard61 keys1532:0257 wiredrazer-huntsman-mini.toml
Razer Huntsman V2keyboard108 keys1532:026C wiredrazer-huntsman-v2.toml
Razer Huntsman V2 Tenkeylesskeyboard87 keys1532:026B wiredrazer-huntsman-v2-tkl.toml
Razer Huntsman V3 Prokeyboard106 keys1532:02A6 wiredrazer-huntsman-v3-pro.toml
Razer Huntsman V3 Pro Tenkeylesskeyboard87 keys1532:02A7 wiredrazer-huntsman-v3-pro-tkl.toml
Razer Ornata V3keyboard10 keys1532:028F wired
1532:02A1 wired
razer-ornata-v3.toml
Razer Basilisk V3mouselogo, scroll wheel, strip ×91532:0099 wiredrazer-basilisk-v3.toml
Razer Basilisk V3 35Kmouselogo, scroll wheel, strip ×91532:00CB wiredrazer-basilisk-v3-35k.toml
Razer Basilisk V3 X HyperSpeedmouse1 zone, device effects only1532:00B9 donglerazer-basilisk-v3-x-hyperspeed.toml
Razer Cobramouse1 zone, device effects only1532:00A3 wiredrazer-cobra.toml
Razer Cobra Promouselogo, scroll wheel, underglow ×9, device effects only1532:00AF wired
1532:00B0 dongle
razer-cobra-pro.toml
Razer DeathAdder V2mousescroll wheel, logo1532:0084 wiredrazer-deathadder-v2.toml
Razer DeathAdder V3mouseno lighting1532:00B2 wiredrazer-deathadder-v3.toml
Razer DeathAdder V3 Promouseno lighting1532:00B6 wired
1532:00B7 dongle
1532:00C2 wired
1532:00C3 dongle
razer-deathadder-v3-pro.toml
Razer Naga V2 Promouselogo, numpad1532:00A7 wired
1532:00A8 dongle
razer-naga-v2-pro.toml
Razer Viper Minimouse1 zone1532:008A wiredrazer-viper-mini.toml
Razer Viper V2 Promouseno lighting1532:00A5 wired
1532:00A6 dongle
razer-viper-v2-pro.toml
Razer Viper V3 Promouseno lighting1532:00C0 wired
1532:00C1 dongle
razer-viper-v3-pro.toml
Razer Firefly V2mousematedge ×191532:0C04 wiredrazer-firefly-v2.toml
Razer Strider Chromamousematedge ×191532:0C05 wiredrazer-strider-chroma.toml
Razer Base Station V2 Chromaotherbase ×81532:0F20 wiredrazer-base-station-v2-chroma.toml
Razer Mouse Dock Prootherbase ×81532:00A4 wiredrazer-mouse-dock-pro.toml

Both tables are generated from the files in devices/ and devices/experimental/, the same files compiled into uncoild. The experimental files are written by tools/devices/gen_experimental.py from the OpenRazer / OpenRGB research; each one says in comments where its values came from and how sure they are. “Device effects only” means the sources disagree about per-LED lighting, so uncoil only uses the device’s own effects until someone confirms more. Notes on the supported devices:

  • BlackWidow V4 Pro 75%: wired only for now. The wireless (HyperSpeed dongle) variant is known to OpenRGB as 1532:02B4 but hasn’t been tested, so it isn’t listed. Its 18 underglow LEDs live in odd matrix slots; see Protocol.
  • Basilisk V3 Pro: wired and HyperSpeed dongle. The dongle answers “no answer” (0x04) while the mouse is on its cable; uncoil treats that as “not here yet” and picks the mouse up on whichever path answers.
  • Goliathus Chroma Extended: the whole edge strip is one LED, sampled at the centre of the mat.

Adding a device

Supporting a device should be a file, not a fork. A device definition says how to reach the device over USB, which quirks it has, what its LED matrix looks like, and where each LED physically sits.

You can try a definition without rebuilding anything: drop the .toml into %APPDATA%\uncoil\devices\ and restart the uncoil task. Files there are loaded after the built-in ones, and a file with the same id as a built-in replaces it. Once it works, open a pull request adding it to devices/ so it ships for everyone.

Where the facts come from

  1. OpenRGB and OpenRazer already know most Razer devices: product id, interface, the LED matrix size and order, and the transaction id. Their source is the first place to look.
  2. Synapse’s own logs, if you still have Synapse installed, record every command it sends to the device, with the raw bytes. tools/reference/mine_synapse_logs.py turns them into a catalog. See Protocol.
  3. The device itself. The small Python probes in tools/reference/ send single commands and read back the status codes, and preview.py renders an effect onto a layout as an animated GIF, so a misplaced LED shows.

Anatomy of a device file

The smallest real example, the Goliathus mat:

devices/razer-goliathus-chroma-extended.toml
id = "razer-goliathus-chroma-extended" # stable id, used in config.json "desk"
name = "Razer Goliathus Chroma Extended"
kind = "mousemat" # keyboard | mouse | mousemat | headset | other
vendor_id = 0x1532
features = ["lighting", "hw_effects"] # what it can do; the default is ["lighting"]
[[usb]] # one entry per way of connecting
product_id = 0x0C02
connection = "wired" # free text: wired, dongle, ...
interface = 0 # HID interface, usage page and usage pick the
usage_page = 0x01 # collection that answers feature reports
usage = 0x02
transaction_id = 0x3F # 0x1F for most keyboards and mice
[quirks]
ack_every_report = false # read the reply after every report
custom_mode_once = true # send the custom-frame effect once, not per frame
[matrix]
rows = 1
cols = 1
names = [["Edge"]] # LED name per (row, col); "" = no LED in that slot
[layout]
type = "points" # explicit LED points, relative to the device centre
width = 26.25 # footprint in key units (1u = 19.05 mm)
depth = 9.75
points = [[0.0, 0.0]] # one [x, y] per LED, in matrix order
[hw_effects] # the device's own (firmware) effects uncoil may set
led = 0x00 # LED / region id for 0F/02; 0 = whole device
effects = ["off", "static", "breathing", "spectrum"]

features and the sections that go with them

features lists what the device can do: lighting (streamed frames, needs [matrix] and [layout]), hw_effects, keymap, profiles, dial, oled, dpi, poll_rate and power. The daemon refuses a command for a feature the file doesn’t list. Most features need their own section: [hw_effects], [keymap] (the key or button ids and their factory mappings), [dpi], [poll_rate] and [power]. A device without RGB has no [matrix] or [layout] and is opened for commands only. The BlackWidow and Basilisk files show every section in use.

Also optional: support = "experimental" (and the file lives in devices/experimental/), unverified = [...] for features nobody has confirmed on that device yet (their writes wait for a read-only check), [sources], and per [[usb]] entry alt_usages, reply_wait_us and [usb.transaction_ids]. Unknown keys are errors that name the file and the field. The full list is in docs/ARCHITECTURE.md.

[[usb]]

Each entry is one way the device can be connected. uncoil opens the HID collection matching interface, usage_page and usage, and talks to it with the given transaction_id. A wireless mouse usually has two entries: the cable and the dongle.

[quirks]

KeyDefaultWhen to set it
ack_every_reportfalseThe device silently stops applying frames after a while unless each reply is read back. The BlackWidow needs this.
custom_mode_oncetrueRe-sending the custom-frame effect every frame freezes the device on its first frame. True for everything seen so far.

[matrix]

The LED matrix as the firmware addresses it: rows × cols, with the name of the LED in each slot and "" where there is none. Names matter for keyboards, where they are matched to the physical key layout.

[layout]: points

For mice, mats and anything that isn’t a keyboard. points lists an [x, y] per LED, in key units relative to the device centre, in row-major matrix order. The Basilisk’s strip, for example, runs down the left side, around the back and up the right.

[layout]: keyboard

Keyboards describe their physical rows instead, and LEDs are matched to keys by name:

[layout]
type = "keyboard"
width = 16.25
depth = 6.25
[[layout.rows]]
y = 0.0
keys = ["Escape:1", "gap:0.25", "F1:1", "F2:1", "F3:1", "F4:1", "gap:0.25", "F5:1"] # "name:width"
# Underglow LEDs just outside the case, back to front, named prefix + index (LU0..LU8, RU0..RU8)
[layout.underglow]
left = { prefix = "LU", x = -0.55, count = 9 }
right = { prefix = "RU", x = 16.8, count = 9 }
y_start = 0.2
y_end = 6.05

Each row lists keys left to right from x = 0 as "name:width" in key units; gap:w is empty space. The name must match the name used in [matrix].

Checking a new definition

  • cargo test -p uncoil-core parses and validates every built-in definition and checks that every named keyboard slot lands on the desk.
  • The desktop app’s Lighting view draws each placed device with its LEDs coloured by the live effect, which shows a wrong position or a mirrored strip at a glance.
  • %LOCALAPPDATA%\uncoil\uncoild.log says whether the device was found and opened.

If a device needs more than data (a new command, a new transport behaviour), open an issue with what you found; see Contributing.