A macOS CLI tool for remapping keyboard keys on a per-device basis. Powered by hidutil under the hood, configured with a simple YAML file.
Useful when you have multiple keyboards with different layouts and want consistent key bindings across all of them.
go install github.com/migfernandes01/monk@latestOr build from source:
git clone https://github.com/migfernandes01/monk.git
cd monk
go build -o monk .- Find your keyboard's device IDs:
monk list-devicesOutput:
PRODUCT VENDOR ID PRODUCT ID TRANSPORT
------- --------- ---------- ---------
USB Gaming Keyboard 0x1a2c 0x95f6 USB
USB Receiver 0x046d 0xc52b USB
Apple Internal Keyboard / Trackpad 0x0000 0x0000 FIFO
- Create a config file at
~/.config/monk/config.yaml:
devices:
- name: "USB Gaming Keyboard"
vendor_id: 0x1a2c
product_id: 0x95f6
mappings:
- from: insert
to: grave- Install the daemon so mappings persist across reboots and apply automatically when devices connect:
monk installThat's it. The Insert key on that keyboard now types backticks — and will continue to work after reboots, sleep/wake, and even if you unplug and replug the keyboard.
Reads the config file and applies all key mappings once via hidutil.
monk apply # uses default config path
monk apply --config ./my.yaml # uses a custom config fileClears all key mappings.
monk reset # reset all devices
monk reset --device 0x1a2c:0x95f6 # reset a specific deviceRuns in the foreground, polling for device connections every 5 seconds. When a configured device is detected, its mappings are applied automatically. If a device disconnects and reconnects, mappings are re-applied.
monk daemon # uses default config path
monk daemon --config ./my.yaml # uses a custom config fileYou typically don't need to run this directly — use install instead.
Sets up a macOS LaunchAgent that runs monk daemon in the background. The daemon starts automatically on login and restarts if it crashes.
monk install # uses default config path
monk install --config ./my.yaml # uses a custom config fileLogs are written to ~/.config/monk/daemon.log.
Stops the daemon, removes the LaunchAgent, and clears all key mappings for every device in the config.
monk uninstallLists all connected keyboard devices with their vendor and product IDs. Use this to find the IDs you need for your config.
monk list-devicesPrints all supported key names and their HID codes.
monk list-keysThe config file lives at ~/.config/monk/config.yaml by default. You can override the path with --config.
Each device is identified by its vendor_id and product_id (find them with list-devices). Mappings define from -> to key pairs using human-readable names (see list-keys for the full list).
devices:
- name: "My External Keyboard"
vendor_id: 0x046d
product_id: 0xc52b
mappings:
- from: caps_lock
to: escape
- from: left_alt
to: left_gui
- from: left_gui
to: left_altTo apply mappings to all connected keyboards, use the name "all" and omit the vendor/product IDs:
devices:
- name: "all"
mappings:
- from: caps_lock
to: left_controlYou can define mappings for as many devices as you want in a single config file:
devices:
- name: "Built-in Keyboard"
vendor_id: 0x05ac
product_id: 0x0342
mappings:
- from: caps_lock
to: escape
- name: "External Keyboard"
vendor_id: 0x046d
product_id: 0xc52b
mappings:
- from: left_alt
to: left_gui
- from: left_gui
to: left_alt| Key Name | Description |
|---|---|
caps_lock |
Caps Lock |
escape |
Escape |
left_control |
Left Control |
left_shift |
Left Shift |
left_alt |
Left Alt/Option |
left_gui |
Left Command |
right_control |
Right Control |
right_shift |
Right Shift |
right_alt |
Right Alt/Option |
right_gui |
Right Command |
tab |
Tab |
return |
Return/Enter |
space |
Space |
delete |
Backspace |
delete_forward |
Forward Delete |
insert |
Insert |
grave |
Backtick / Grave |
fn |
Fn (Apple) |
f1 - f12 |
Function keys |
a - z |
Letter keys |
0 - 9 |
Number keys |
up_arrow |
Up Arrow |
down_arrow |
Down Arrow |
left_arrow |
Left Arrow |
right_arrow |
Right Arrow |
Run monk list-keys for the complete list with HID codes.
hidutil mappings are cleared on every reboot. The install command solves this by creating a macOS LaunchAgent (~/Library/LaunchAgents/com.monk.plist) that runs a background daemon.
The daemon:
- Starts automatically on login
- Polls for connected devices every 5 seconds
- Applies the correct mappings when a configured device is detected
- Re-applies mappings if a device disconnects and reconnects
- Restarts automatically if it crashes (
KeepAlive)
This means you can write your config once and it works across reboots, sleep/wake cycles, and hot-plugging — whether you're at home, the office, or anywhere else.
To stop persistence, run monk uninstall.