Razer control on Windows,
without Synapse.

A complete port of OpenRazer to Windows 10 and 11. The Linux kernel driver becomes user-space HID, D-Bus becomes a loopback daemon, and every per-device quirk is transpiled straight from the upstream C sources.

268 devices Zero dependencies No kernel driver No admin rights No telemetry GPL-2.0-or-later on PyPI

01Install

Python 3.9 or newer on Windows 10 / 11 (amd64). Nothing else.

pip install openrazer-win

# optional, for Bluetooth-only devices such as the Kraken Kitty V2 BT
pip install "openrazer-win[ble]"

The entire port runs on the standard library — no compiler, no hidapi wheel, no driver signing, no reboot. Prefer a single file? Download openrazer-win.exe from the latest release; it needs no Python at all.

Close Razer Synapse first. Synapse holds the device open and will fight you for the LEDs. Run openrazer-win doctor to check.

02Usage

A command line, a Python API and a small graphical panel — pick whichever suits.

# start the background service, then look around
openrazer-win daemon start
openrazer-win list
openrazer-win info

# lighting
openrazer-win effect static red
openrazer-win effect spectrum
openrazer-win effect wave --direction 2
openrazer-win effect breath_dual "#ff0080" --colour2 cyan
openrazer-win effect ripple green   # follows your typing

# one colour per zone -- on the Bluetooth headset, one per ear
openrazer-win zones
openrazer-win zones red blue

# named lighting profiles, kept on this PC
openrazer-win profile save night
openrazer-win profile load night

# settings
openrazer-win brightness 60
openrazer-win dpi 1800
openrazer-win poll-rate 1000
openrazer-win battery

# start the daemon with Windows (per-user, no admin rights)
openrazer-win autostart enable

Every command accepts --device (serial, product id or part of the name), --zone and --json. Autostart writes a single HKCU\…\Run entry, so it shows up in Task Manager's Startup tab too.

03How it works

The Linux stack is a kernel module plus a D-Bus daemon. Neither exists on Windows, so each layer gets a direct replacement.

Linux and Windows layer stacks side by side, with the Razer vendor protocol shared between them LINUX (UPSTREAM) WINDOWS (THIS PORT) openrazer.client D-Bus session bus openrazer-daemon python + dbus-python razerkbd.ko / razermouse.ko sysfs attributes, usb_control_msg() kernel space — needs DKMS usbhid / usbcore openrazer_win.client JSON-RPC over loopback TCP openrazer_win.daemon bearer token, hot-plug watcher openrazer_win.devices 565 recipes transpiled from the same C user space — pip install, no reboot hid.dll + setupapi.dll via ctypes transpiled Razer vendor protocol — one 90-byte HID feature report, XOR checksum over bytes 2–87
The protocol is identical on both sides; only the transport and the quirk storage differ.

The interesting part: transpiled quirks

OpenRazer's drivers encode roughly 20 000 lines of per-device behaviour as switch (device->usb_pid) statements — which report builder to call, which LED id, which transaction id. Hand-porting that would guarantee drift from upstream.

Instead a transpiler parses the C, folds every switch against each known product id, and emits a tiny program per (attribute, device):

[{"op": "build", "fn": "razer_chroma_extended_matrix_effect_static",
  "args": [{"k": "const", "value": 1}, {"k": "var", "name": "led_id"},
           {"k": "rgb", "offset": 0}]},
 {"op": "txid", "value": {"k": "const", "value": 63}},
 {"op": "send"}]

565 distinct recipes cover all 267 devices, and a runtime interpreter executes them. Tracking a new upstream release means re-running the transpiler, not rewriting Python.

🔌

Finding the device

The kernel addresses a USB interface directly. Windows exposes each as its own HID collection, so the port picks the one whose path carries the matching &mi_XX and declares a 90-byte feature report.

🔓

Exclusive access

Windows denies read/write on keyboard and mouse collections. Feature-report IOCTLs are FILE_ANY_ACCESS, so the port falls back to a zero-access handle and still talks to the device.

🧪

Tested without hardware

A built-in emulator validates CRCs and answers the protocol. 315 tests plus a fleet simulation exercise every capability of all 267 devices on every commit.

⌨️

Ripple on Windows

Upstream reads /dev/input to place ripples. Here a low-level keyboard hook observes key presses — it never swallows or synthesises input — and the host renders the frames.

💾

State that survives sleep

Windows cuts USB power on suspend. The daemon records what was applied per serial and replays it when the device reappears.

🎧

A second protocol

Kraken headsets predate the control report: they expose the lighting controller's RAM. Colours go to fixed addresses, then one byte says what to do with them — ported from razerkraken_driver.c by hand, since it has no switch tables to transpile.

📡

A protocol nobody documented

The Kraken Kitty V2 BT has no USB data mode, so upstream has no driver for it. Its lighting was recovered here from a Bluetooth HCI capture: a vendor GATT service whose UUID spells Amel-RazerBLE, taking c4 00 06 and one RGB triple per ear. Each ear can be given its own colour, in a single write. It stores none of it, so the colour is held for as long as the daemon runs, and named profiles keep as many of those as you like.

🔐

Local only

The daemon binds loopback, generates a random bearer token in an owner-only file, and exposes a fixed allowlist of methods. It never touches the network.

04Supported devices

Every product id OpenRazer knows about, generated from the upstream device classes. Search by name, or filter by category.

DeviceTypeProduct id MatrixMax DPIBattery
Loading…

05Troubleshooting

Start here — it lists every Razer HID collection Windows can see and marks the control interface.

openrazer-win doctor
SymptomCause
no Razer control interface Synapse is running, or another program holds the device. Close it.
Device shown as NOT IN DATABASE Newer than the bundled data. Open an issue with the product id.
device replied not supported The firmware refused that command; the device genuinely lacks the feature.
Effects reset after sleep Windows cuts USB power. The daemon replays stored state on reconnect.
A Bluetooth device is on, but not listed Install the extra: pip install "openrazer-win[ble]". doctor ends with a Bluetooth section saying whether support is present and what the radio can hear.
Nothing listed at all Only Razer devices (vendor 1532) are handled.

Not ported