karabiner
Configure and manage Karabiner-Elements key remapping. Use when modifying karabiner.json, adding key remappings, creating complex modifications, managing profiles, setting variables, or troubleshooting keybinding issues.
Installation
Follow the repository instructions for this skill and your agent. Review the files and dependencies before adding it to your workflow.
View source ↗GuidesSkill instructions
Karabiner-Elements configuration skill
Overview
Manage Karabiner-Elements configuration for macOS keyboard customization including key remapping, complex modifications, and profile management.
Configuration locations
- Config file:
~/.config/karabiner/karabiner.json - CLI tool:
/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_cli - Assets:
~/.config/karabiner/assets/complex_modifications/
Current configuration
Complex modifications (internal keyboard only)
- caps lock → left control: Caps lock acts as control
- right command → hyper: Right command acts as cmd+shift+ctrl+opt
- right option → meh: Right option acts as shift+ctrl+opt
All modifications are limited to the internal MacBook keyboard using device_if conditions with is_built_in_keyboard: true.
CLI operations
Profile management
karabiner_cli --select-profile 'Default profile'
karabiner_cli --show-current-profile-name
karabiner_cli --list-profile-names
Device inspection
List connected devices:
karabiner_cli --list-connected-devices
Returns JSON with device information:
-
device_id: unique device identifier -
device_identifiers: keyboard/pointing device flags, vendor/product IDs -
is_built_in_keyboard/is_built_in_pointing_device: built-in device flags -
manufacturer,product: device name and manufacturer -
transport: connection type (USB, Bluetooth, FIFO, Audio)
Useful for finding vendor_id and product_id for device-specific mappings.
List system variables:
karabiner_cli --list-system-variables
Shows current system state variables:
-
system.now.milliseconds: current timestamp -
system.scroll_direction_is_natural: natural scrolling enabled -
system.use_fkeys_as_standard_function_keys: function key behavior -
system.temporarily_ignore_all_devices: temporary disable flag
Variable management
Set variables for complex modifications:
karabiner_cli --set-variables '{"cli_flag1":1, "cli_flag2":2}'
Use --silent flag to suppress output.
Development tools
Run JavaScript files:
karabiner_cli --eval-js path/to/script.js
Executes JavaScript using Duktape engine. Useful for generating or manipulating complex modifications programmatically.
Lint configuration:
karabiner_cli --lint-complex-modifications ~/.config/karabiner/karabiner.json
Format JSON:
karabiner_cli --format-json ~/.config/karabiner/karabiner.json
System operations
Copy profile to system default (requires admin):
sudo karabiner_cli --copy-current-profile-to-system-default-profile
Remove system default profile:
sudo karabiner_cli --remove-system-default-profile
Version info
karabiner_cli --version
karabiner_cli --version-number
Configuration structure
Profile format
{
"profiles": [
{
"name": "Default profile",
"selected": true,
"complex_modifications": { "rules": [...] },
"devices": [...],
"simple_modifications": [...],
"virtual_hid_keyboard": { "keyboard_type_v2": "ansi" }
}
]
}
Complex modification rule
{
"description": "Description of the rule",
"manipulators": [
{
"type": "basic",
"from": {
"key_code": "h",
"modifiers": { "mandatory": ["left_option"] }
},
"to": { "key_code": "left_arrow" }
}
]
}
Advanced manipulator features
Tap vs hold:
{
"from": { "key_code": "return_or_enter" },
"to_if_alone": [{ "key_code": "return_or_enter" }],
"to_if_held_down": [{
"key_code": "left_shift",
"modifiers": ["right_shift", "left_control", "left_option"]
}],
"parameters": {
"basic.to_if_held_down_threshold_milliseconds": 200
}
}
Delayed actions:
{
"to_delayed_action": {
"to_if_canceled": [{ "key_code": "return_or_enter" }]
},
"parameters": {
"basic.to_delayed_action_delay_milliseconds": 200
}
}
Device-specific mappings
{
"identifiers": {
"is_keyboard": true,
"product_id": 834,
"vendor_id": 1452
},
"simple_modifications": [
{
"from": { "key_code": "fn" },
"to": [{ "key_code": "escape" }]
}
]
}
Special device options:
-
ignore: true- ignore this device -
disable_built_in_keyboard_if_exists: true- disable built-in when this device connected -
treat_as_built_in_keyboard: true- treat as built-in keyboard -
manipulate_caps_lock_led: false- don't manipulate caps lock LED
Common key codes
Modifiers
-
left_command,right_command -
left_control,right_control -
left_shift,right_shift -
left_option,right_option -
caps_lock,fn
Special keys
-
return_or_enter,escape,delete_or_backspace -
tab,spacebar -
up_arrow,down_arrow,left_arrow,right_arrow -
page_up,page_down,home,end
Modifier specifications
{
"modifiers": {
"mandatory": ["left_option"],
"optional": ["caps_lock", "any"]
}
}
Common patterns
Simple key remap
{
"description": "caps lock to escape",
"manipulators": [{
"type": "basic",
"from": { "key_code": "caps_lock" },
"to": [{ "key_code": "escape" }]
}]
}
Modifier + key to key
{
"description": "opt+h to left arrow",
"manipulators": [{
"type": "basic",
"from": {
"key_code": "h",
"modifiers": { "mandatory": ["left_option"] }
},
"to": [{ "key_code": "left_arrow" }]
}]
}
Hyper key (tap for key, hold for modifier)
{
"description": "return to hyper when held",
"manipulators": [{
"type": "basic",
"from": { "key_code": "return_or_enter" },
"to_if_alone": [{ "key_code": "return_or_enter" }],
"to_if_held_down": [{
"key_code": "left_shift",
"modifiers": ["right_shift", "left_control", "left_option"],
"repeat": false
}],
"parameters": {
"basic.to_if_held_down_threshold_milliseconds": 200
}
}]
}
Working with configuration
Validate changes
After editing karabiner.json:
- Karabiner-Elements automatically reloads on file change
- Check EventViewer to verify key mappings work
- Use
karabiner_cli --lint-complex-modificationsto validate
Adding new rules
- Edit
~/.config/karabiner/karabiner.json - Add new rule to
profiles[0].complex_modifications.rules - Save file (auto-reload triggers)
- Test in EventViewer
Testing key codes
- Open Karabiner-Elements > Misc > Launch EventViewer
- Press keys to see their key codes
- Use codes in configuration
Device condition patterns
Limiting rules to built-in keyboard
{
"conditions": [
{
"identifiers": [
{
"is_built_in_keyboard": true
}
],
"type": "device_if"
}
]
}
Use device_if conditions to limit modifications to specific devices. The is_built_in_keyboard flag targets only the internal MacBook keyboard, ignoring all external keyboards.
Other device condition options
-
is_built_in_keyboard: Internal MacBook keyboard -
is_pointing_device: Trackpads and mice -
vendor_id+product_id: Specific device by identifiers -
device_unless: Inverse condition (apply to all except specified devices)
Integration with other tools
Hammerspoon relationship
- Karabiner: Low-level key remapping at OS level
- Hammerspoon: High-level automation and app control
- Use Karabiner for modifier/key remaps, Hammerspoon for actions
Current setup:
- Karabiner creates hyper and meh modifiers from right command/option
- Hammerspoon can bind hyper/meh keys to app launches and window management
Troubleshooting
Changes not taking effect
- Check JSON syntax is valid
- Ensure Karabiner-Elements is running
- Check Security & Privacy settings allow Karabiner
- Restart Karabiner-Elements:
killall Karabiner-Elements && open -a Karabiner-Elements
Device not recognized
- Check
identifiersmatch in EventViewer - Verify
is_keyboard: trueis set - Try unplugging and reconnecting device
Complex modification not working
- Test key codes in EventViewer
- Check modifier combinations are correct
- Verify no conflicting rules exist
- Check rule order (first matching rule wins)
Profile issues
karabiner_cli --list-profile-names
karabiner_cli --show-current-profile-name
karabiner_cli --select-profile 'ProfileName'
Resources
- Karabiner-Elements docs: https://karabiner-elements.pqrs.org/docs/
- Complex modifications gallery: https://ke-complex-modifications.pqrs.org/
- EventViewer: Karabiner-Elements > Misc > Launch EventViewer
Examples
Read the usage examples in the source repository.
View source ↗Source history
- Indexed on
- 2026-01-20
- Index updated
- 2026-01-26
- Branch
- main
Index and sync dates describe this directory. View the source repository for code history.
GitHub ↗chat Comments (0)
Sign in to join the discussion and leave a comment.
No comments yet. Be the first to share your thoughts!