Logitech mouse control for macOS

Your mouse, minus the 4 GB.

A nibble is half a byte. This one is a 516 KB command-line tool that controls your Logitech mouse natively on macOS — no daemon, no account, no telemetry.

Get Nibble on GitHub
516 KB binary Zero dependencies Open source · MIT
zsh — nibble
$ nibble status
device    G502 LIGHTSPEED · receiver 046D:C539
protocol  HID++ 4.2 · link ok
battery   50% · 3.85 V · charging
dpi       1600
rate      1000 Hz
mode      host

$ nibble dpi 3200
dpi 3200 ✓  read back from device

$ nibble battery
50% 3.85V charging
$ 
The pitch, to scale

G HUB is a 4 GB install. Nibble is 516 KB.

G HUB
4 GB
Options+
~800 MB
Nibble
516 KB

Drawn to scale, 516 KB would be 0.12 px wide — we rounded up so you can see it.

Why Nibble

Small, native, and honest.

516 KB. Zero dependencies.

One static binary built with make. No runtime, no installer, no framework — nothing to keep updated.

Nothing lives in the background.

No daemon, no telemetry, no account. Nibble runs, applies, exits. The opt-in menu bar is the only resident mode — it also hosts button remapping.

Speaks HID++ 4.2, natively.

Raw protocol over your Lightspeed / Unifying receiver through IOKit — the same language G HUB speaks.

Every write is verified.

Set DPI 50–25600 or a 125–1000 Hz report rate — each write is read back from the device and confirmed, with honest exit codes for scripts.

Battery, in real volts.

Millivolt readings through a LiPo curve, one script-friendly line. Kill the RGB with one command to buy the hours back.

Set once. Replays at login.

Your config is a tiny JSON; a one-shot launchd agent re-applies it at login and exits. Onboard flash stays read-only — with a full backup as your escape hatch.

The CLI

One binary. Every control.

CommandEffect
nibble statusOverview: link, battery, DPI, report rate, feature flags
nibble batteryOne line, script-friendly: 50% 3.85V charging
nibble doctorDiagnose permissions, device, config, engine — each failure prints its fix
nibble dumpEnumerate all HID++ features (diagnostic)
nibble dpi [50-25600]Get / set DPI, verified by read-back
nibble rate [125|250|500|1000]Get / set report rate in Hz
nibble rgb off|showLights off (power saving) / list zones and effects
nibble mode [host|onboard]Get / set control-mode flag
nibble wheel free|ratchetSmartShift wheel mode — MX-series only (untested)
nibble onboard info|backupOnboard memory info / read-only full dump
nibble config init|showCreate from current state / print ~/.config/nibble.json
nibble applyApply the config file (runtime writes)
nibble replay install|uninstallAuto-apply at login via a one-shot launchd agent
nibble buttonsEnumerate programmable buttons (0x1b04 MX-series / 0x8110 G-series)
nibble spy [seconds]Live button-event monitor, G-series diagnostic
nibble remapInteractive remap: press a button → assign keystroke / system action / disable
nibble menubarInteractive menu bar: battery + DPI/rate/RGB; hosts the remap engine (~15 MB, opt-in)
Nibble.appMenu bar launched from Finder (make app) — adds low-battery notifications
nibble uiNative settings window (General + Buttons tabs); quits when closed
Debug: NIBBLE_DEBUG=1 · Exit codes: 0 ok · 1 no awake device / not applied · 2 transport error · 64 usage · --json on every read command
Get started

Three lines to a configured mouse.

Install

macOS with the Swift toolchain (xcode-select --install). Logitech mouse on a USB receiver — Lightspeed / Unifying; Bluetooth-direct not yet. Tested on G502 LIGHTSPEED.

brew tap ben0128/nibble
brew trust ben0128/nibble
brew install nibble

Or build from source (Command Line Tools are enough):

git clone https://github.com/ben0128/nibble && cd nibble
make
./nibble status
First run: grant Input Monitoring — System Settings → Privacy & Security → Input Monitoring → enable your terminal, then re-run. Error 0xE00002E2 just means the permission is missing; no restart needed. Button remapping additionally needs Accessibility (prompted on first engine start).

~/.config/nibble.json

Create it from your current state with nibble config init. Omitted keys are left untouched.

{
  "dpi": 1600,
  "reportRateHz": 1000,
  "rgb": "off"
}

Also available: wheelMode "free" / "ratchet" and wheelThreshold 1–254 (MX-series). Then nibble apply — or nibble replay install to re-apply at every login.

Runtime writes, by design

Writes go to device RAM — a power cycle reverts to the onboard profile. replay re-applies your config at login, in one shot.

Host mode, handled

Report-rate and RGB writes need the host-mode flag; commands flip it automatically and it reverts with the mouse.

Your flash stays yours

Onboard flash is read-only by design. onboard backup dumps every sector — restore factory settings via G HUB on any machine, any time.