~/.config/karabiner/karabiner.json Main configuration file.
Karabiner-Elements watches this file and reload it automatically when it is updated.
~/.config/karabiner/assets/complex_modifications Imported complex_modifications files.
You can use them in Preferences > Complex Modifications > Add rule.

Automation reload mechanism

Karabiner-Elements watches ~/.config/karabiner/karabiner.json and reloads it if updated.

The mechanism is that Karabiner-Elements watches the parent directory ~/.config/karabiner by using the File System Events API.
Thus, Karabiner-Elements fails detecting file updates after you change the parent directory (e.g., recreate the parent directory).

Error messages

Error messages will be output into ~/.local/share/karabiner/log/console_user_server.log if there are errors such as parse error.

You can also view the error messages in Karabiner-Elements Preferences > Log.

Swap ; and :.

{
    "type": "basic",
    "from": {
        "key_code": "semicolon",
        "modifiers": {
            "mandatory": [
                "shift"
            ],
            "optional": [
                "caps_lock"
            ]
        }
    },
    "to": [
        {
            "key_code": "semicolon"
        }
    ]
},

{
    "type": "basic",
    "from": {
        "key_code": "semicolon",
        "modifiers": {
            "optional": [
                "caps_lock"
            ]
        }
    },
    "to": [
        {
            "key_code": "semicolon",
            "modifiers": [
                "left_shift"
            ]
        }
    ]
}

Change control-h to delete. (And option-control-h to option-delete.)

{
    "type": "basic",
    "from": {
        "key_code": "h",
        "modifiers": {
            "mandatory": [
                "control"
            ],
            "optional": [
                "caps_lock",
                "option"
            ]
        }
    },
    "to": [
        {
            "key_code": "delete_or_backspace"
        }
    ]
}

Disable command-l on Finder.

{
    "type": "basic",
    "from": {
        "key_code": "l",
        "modifiers": {
            "mandatory": [
                "command"
            ],
            "optional": [
                "caps_lock"
            ]
        }
    },
    "conditions": [
        {
            "type": "frontmost_application_if",
            "bundle_identifiers": [
                "^com\\.apple\\.finder$"
            ]
        }
    ]
}

Post escape if left_control is pressed alone.

{
    "type": "basic",
    "from": {
        "key_code": "left_control",
        "modifiers": {
            "optional": [
                "any"
            ]
        }
    },
    "to": [
        {
            "key_code": "left_control",
            "lazy": true
        }
    ],
    "to_if_alone": [
        {
            "key_code": "escape"
        }
    ]
}

Open Alfred 3 if escape is held down.

{
    "type": "basic",
    "from": {
        "key_code": "escape",
        "modifiers": {
            "optional": [
                "caps_lock"
            ]
        }
    },
    "parameters": {
        "basic.to_if_alone_timeout_milliseconds": 250,
        "basic.to_if_held_down_threshold_milliseconds": 250
    },
    "to_if_alone": [
        {
            "key_code": "escape"
        }
    ],
    "to_if_held_down": [
        {
            "shell_command": "open -a 'Alfred 3.app'"
        }
    ]
}

Change right_shift x2 to mission_control.

{
    "type": "basic",
    "from": {
        "key_code": "right_shift",
        "modifiers": {
            "optional": [
                "any"
            ]
        }
    },
    "to": [
        {
            "key_code": "mission_control"
        }
    ],
    "conditions": [
        {
            "type": "variable_if",
            "name": "right_shift pressed",
            "value": 1
        }
    ]
},

{
    "type": "basic",
    "from": {
        "key_code": "right_shift",
        "modifiers": {
            "optional": [
                "any"
            ]
        }
    },
    "to": [
        {
            "set_variable": {
                "name": "right_shift pressed",
                "value": 1
            }
        },
        {
            "key_code": "right_shift"
        }
    ],
    "to_delayed_action": {
        "to_if_invoked": [
            {
                "set_variable": {
                    "name": "right_shift pressed",
                    "value": 0
                }
            }
        ],
        "to_if_canceled": [
            {
                "set_variable": {
                    "name": "right_shift pressed",
                    "value": 0
                }
            }
        ]
    }
}

Change equal+delete to forward_delete if these keys are pressed simultaneously.

{
    "type": "basic",
    "from": {
        "simultaneous": [
            {
                "key_code": "equal_sign"
            },
            {
                "key_code": "delete_or_backspace"
            }
        ],
        "modifiers": {
            "optional": [
                "any"
            ]
        }
    },
    "to": [
        {
            "key_code": "delete_forward"
        }
    ]
}

karabiner.json

{
    "global": {
        ...
    },
    "profiles": [
        {
            "name": "Profile name",
            "selected": true,
            "simple_modifications": [
                ...
            ],
            "fn_function_keys": [
                ...
            ],
            "complex_modifications": {
                "parameters": {
                    ...
                },
                "rules": [
                    ...
                ]
            },
            "virtual_hid_keyboard": {
                "keyboard_type": "ansi",
                "caps_lock_delay_milliseconds": 0
            },
            "devices": [
                ...
            ]
        },
        {
            "name": "Profile name",
            "selected": false,
            ...
        },
        ...
    ]
}

complex_modifications in karabiner.json > profiles

{
    "complex_modifications": {
        "parameters": {
            ...
        },
        "rules": [
            {
                "description": "This description is shown in Preferences.",
                "manipulators": [
                    {
                        "type": "basic",

                        "from": from event definition,

                        "to": [
                            to event definition,
                            to event definition,
                            ...
                        ],

                        "to_if_alone": [
                            to event definition,
                            to event definition,
                            ...
                        ],

                        "to_if_held_down": [
                            to event definition,
                            to event definition,
                            ...
                        ],

                        "to_after_key_up": [
                            to event definition,
                            to event definition,
                            ...
                        ],

                        "to_delayed_action": {
                            "to_if_invoked": [
                                to event definition,
                                to event definition,
                                ...
                            ],
                            "to_if_canceled": [
                                to event definition,
                                to event definition,
                                ...
                            ]
                        },

                        "conditions": [
                            condition definition,
                            condition definition,
                            ...
                        ],

                        "parameters": {
                            ...
                        },

                        "description": "Optional description for human"
                    },
                    {
                        "type": "basic",
                        ...
                    },
                    ...
                ]
            },
            {
                "description": "...",
                "manipulators": [
                    ...
                ]
            },
            ...
        ]
    }
}

The manipulators are evaluated from the top to the bottom and the input event is manipulated only the first matched manipulator.

In other words, if there are multiple manipulators which change the same key, the manipulator placed at the top is applied and other manipulators are ignored.

Simple Modifications and Complex Modifications

Simple Modifications and Complex Modifications are independent. Thus, Simple Modifications does not affect above priority.
Input event modification chaining (Simple Modifications, Complex Modifications, Function Keys Modifications) description.

Name Required Description
type required Always "type": "basic"
from required The name of key code, consumer key code or pointing button which you want to change. (detail)
to optional events which are sent when you press from key.
to_if_alone optional events which are sent when you press from key alone.
to_if_held_down optional events which are sent when you hold down from key.
to_after_key_up optional events which are sent after you release from key.
to_delayed_action optional to_delayed_action sends to_delayed_action > to_if_invoked events after 500 milliseconds at you press from key.
to_delayed_action > to_if_canceled events are sent if you press another key between from key and to_delayed_action invoked. (to_if_invoked events are not sent if to_if_canceled events are sent.)
description optional A manipulator description for human.
conditions optional Manipulator is applied only if condition is matched. (The frontmost application, device, etc.)
parameters optional Override parameters such as to_delayed_action_delay_milliseconds.

from event definition

{
    "key_code": "The name of key_code",
    "consumer_key_code": "The name of consumer_key_code",
    "pointing_button": "The name of pointing_button",
    "any": "key_code or consumer_key_code or pointing_button",

    "modifiers": {
        "mandatory": [
            modifier,
            modifier,
            ...
        ],
        "optional": [
            modifier,
            modifier,
            ...
        ]
    },

    "simultaneous": [
        {
           "key_code, consumer_key_code, pointing_button or any"
        },
        {
           "key_code, consumer_key_code, pointing_button or any"
        },
        ...
    ]
}
Name Required Description
key_code optional You can find key_code by EventViewer. (list)
consumer_key_code optional
pointing_button optional
any optional You can use any as follows.
These matches all key codes, consumer key codes or pointing buttons.
  • "any": "key_code"
  • "any": "consumer_key_code"
  • "any": "pointing_button"
modifiers optional Specify modifiers. (e.g., "change control-h to delete") (detail)
simultaneous optional Specify multiple events which are pressed simultaneously. (detail)

modifiers in from event definition

modifiers works as follows.
When modifiers is omitted Events are manipulated only if modifier keys are not pressed.
When modifiers > mandatory is specified Events are manipulated if mandatory modifiers are pressed.
Mandatory modifiers are omitted from to events.
When modifiers > optional is specified Events are also manipulated even if optional modifiers are pressed.
Optional modifiers are kept in to events.

Examples

Change escape to tab without modifiers

{
    "type": "basic",
    "from": {
        "key_code": "escape"
    },
    "to": [
        {
            "key_code": "tab"
        }
    ]
}
key manipulated result
escape manipulated tab
left_shift + escape not manipulated left_shift + escape
left_control + escape not manipulated left_control + escape

Change escape to tab with optional modifiers

{
    "type": "basic",
    "from": {
        "key_code": "escape",
        "modifiers": {
            "optional": [
                "left_shift",
                "left_control"
            ]
        }
    },
    "to": [
        {
            "key_code": "tab"
        }
    ]
}
key manipulated result
escape manipulated tab
left_shift + escape manipulated left_shift + tab
left_control + escape manipulated left_control + tab
left_option + escape not manipulated left_option + escape
left_shift + left_option + escape not manipulated left_shift + left_option + escape
(because left_option is not in optional modifiers)

Change control-h to delete without optional modifiers

{
    "type": "basic",
    "from": {
        "key_code": "h",
        "modifiers": {
            "mandatory": [
                "control"
            ]
        }
    },
    "to": [
        {
            "key_code": "delete_or_backspace"
        }
    ]
}
key manipulated result
h not manipulated h
left_control + h manipulated delete_or_backspace
left_control + left_option + h not manipulated left_control + left_option + h
(because left_option is not in optional modifiers)

Change control-h to delete with optional modifiers

{
    "type": "basic",
    "from": {
        "key_code": "h",
        "modifiers": {
            "mandatory": [
                "control"
            ],
            "optional": [
                "caps_lock",
                "option"
            ]
        }
    },
    "to": [
        {
            "key_code": "delete_or_backspace"
        }
    ]
}
key manipulated result
h not manipulated h
left_control + h manipulated delete_or_backspace
left_control + left_option + h manipulated left_option + delete_or_backspace
left_control + left_shift + h not manipulated left_control + left_shift + h
(because left_shift is not in optional modifiers)

The list of modifiers in from definition

name description
caps_lock
left_command
left_control
left_option
left_shift
right_command
right_control
right_option
right_shift
fn
command left command or right command
control left control or right control
option left option or right option
shift left shift or right shift
any any modifiers

Detail of simultaneous

simultaneous manipulates keys which are pressed simultaneously in 50 milliseconds.

About threshold milliseconds

You can adjust threshold on Preferences > Complex Modifications > Parameters.

It is same as adjusting basic.simultaneous_threshold_milliseconds parameter in json.

About manipulation

There are some cases simultaneous does not modify events.

  • simultaneous does not modify events if any input events are released before all input events are pressed.
  • simultaneous does not modify events if input events are interrupted by another event.

For example, changing a+s+d to mission_control works as the following table.

Input Output Note
  1. a key_down
  2. s key_down
  3. d key_down
  1. mission_control
Manipulated.
  1. s key_down
  2. a key_down
  3. d key_down
  1. mission_control
Manipulated.
The key order is insensitive.
  1. a key_down
  2. s key_down
  3. a key_up
  4. d key_down
  1. a key_down
  2. s key_down
  3. a key_up
  4. d key_down
Not manipulated.
a is released before all input events are pressed.
  1. a key_down
  2. s key_down
  3. f key_down
  4. d key_down
  1. a key_down
  2. s key_down
  3. f key_down
  4. d key_down
Not manipulated.
Another key (f) is pressed before all input events are pressed.

Note: The manipulator definition of changing a+s+d to mission_control.

{
  "type": "basic",
  "from": {
    "simultaneous": [
      {
        "key_code": "a"
      },
      {
        "key_code": "s"
      },
      {
        "key_code": "d"
      }
    ],
    "modifiers": {
      "optional": [
        "any"
      ]
    }
  },
  "to": [
    {
      "key_code": "mission_control"
    }
  ]
}

to event definition

{
    "key_code": "The name of key_code",
    "consumer_key_code": "The name of consumer_key_code",
    "pointing_button": "The name of pointing_button",

    "shell_command": "shell command",

    "select_input_source": {
        "language": "language regex",
        "input_source_id": "input source id regex",
        "input_mode_id": "input mode id regex"
    },

    "set_variable": {
        "name": "variable name",
        "value": "variable value"
    },

    "mouse_key": mouse_key definition,

    "modifiers": [
        modifier,
        modifier,
        ...
    ],

    "lazy": false,
    "repeat": true
}
Name Required Description
key_code optional You can find key_code by EventViewer. (list)
consumer_key_code optional
pointing_button optional
shell_command optional
select_input_source optional You can find the current input source identifiers by EventViewer > Variables tab.
language, input_source_id and input_mode_id are optional. select_input_source finds the input source by the specified regexs.
set_variable optional Set internal variable value by set_variable.
It's designed to use with variable_if and variable_unless conditions.
You can confirm the current variables state in EventViewer > Variables tab.
mouse_key optional Move mouse pointer and scroll by mouse_key.
You can specify operations by combination of follows.
  • { "x": speed }
  • { "y": speed }
  • { "vertical_wheel": speed }
  • { "horizontal_wheel": speed }
  • { "speed_multiplier": 1.0 }
Examples:
  • move left: { "mouse_key": { "x": -1536 } }
  • move right: { "mouse_key": { "x": 1536 } }
  • move up: { "mouse_key": { "y": -1536 } }
  • move down: { "mouse_key": { "y": 1536 } }
  • scroll left: { "mouse_key": { "horizontal_wheel": 32 } }
  • scroll right: { "mouse_key": { "horizontal_wheel": -32 } }
  • scroll up: { "mouse_key": { "vertical_wheel": -32 } }
  • scroll down: { "mouse_key": { "vertical_wheel": 32 } }
  • fast move left: { "mouse_key": { "x": -3072 } }
  • fast move right: { "mouse_key": { "x": 3072 } }
  • fast move up: { "mouse_key": { "y": -3072 } }
  • fast move down: { "mouse_key": { "y": 3072 } }
  • fast scroll left: { "mouse_key": { "horizontal_wheel": 64 } }
  • fast scroll right: { "mouse_key": { "horizontal_wheel": -64 } }
  • fast scroll up: { "mouse_key": { "vertical_wheel": -64 } }
  • fast scroll down: { "mouse_key": { "vertical_wheel": 64 } }
  • speed multiplier x2: { "mouse_key": { "speed_multiplier": 2.0 } }
  • speed multiplier /2: { "mouse_key": { "speed_multiplier": 0.5 } }
modifiers optional Specify modifiers.
lazy optional

true or false. The default value is false.

lazy parameter works with modifier. (e.g., "key_code": "left_shift")
When "lazy": true, the modifier works as the lazy modifier.
The lazy modifier does not send own key events until another key is pressed together.

repeat optional

true or false. The default value is true.

When "repeat": false, both key_down and key_up events are sent when you press the key.
(When "repeat": true, key_up event is sent when you release the key.)

This behavior suppresses the key repeating when "repeat": false.

The list of modifiers in to definition

  • caps_lock
  • left_command
  • left_control
  • left_option
  • left_shift
  • right_command
  • right_control
  • right_option
  • right_shift
  • fn

Detail of to_if_alone

to_if_alone posts events when the from key is pressed alone.
The events are posted at the from key is released.

About cancellation

to_if_alone is canceled if other events (keys, buttons or scroll wheel) is happen while the from key is pressed down.

The cancellation also happens when you press from key long. (The default timeout is 1000 milliseconds.)
You can adjust the timeout milliseconds by parameters > basic.to_if_alone_timeout_milliseconds.
The following examples set the timeout 500 milliseconds.

{
    "from": ...,
    "to": ...,
    "to_if_alone": [
        {
            "key_code": "escape"
        }
    ],
    "parameters": {
        "basic.to_if_alone_timeout_milliseconds": 500
    },
    "type": "basic"
}

About key repeat

to_if_alone posts both key_down and key_up events at the same time.
Thus, you cannot use key repeat for to_if_alone events.

Detail of to_if_held_down

to_if_held_down posts events when the from key is held down.

If to events are specified, to events are released before to_if_held_down are posted.

condition definition

frontmost_application_if and frontmost_application_unless

{
    "type": "frontmost_application_if",
    "bundle_identifiers": [
        bundle identifier regex,
        bundle identifier regex,
        ...
    ],
    "file_paths": [
        file path regex,
        file path regex,
        ...
    ]
}
Name Required Description
type required Either:
  • "type": "frontmost_application_if"
  • "type": "frontmost_application_unless"
bundle_identifiers optional bundle identifier regexs.
You can examine application's bundle identifier in EventViewer > Frontmost Application tab.
file_paths optional file path regexs.
You can examine application's file path in EventViewer > Frontmost Application tab.
description optional A condition description for human.

device_if and device_unless

{
    "type": "device_if",
    "identifiers": [
        {
            "vendor_id": 1111,
            "product_id": 2222,
            "description": "my keyboard 1"
        },
        {
            "vendor_id": 3333,
            "product_id": 4444,
            "description": "my keyboard 2"
        },
        ...
    ]
}
Name Required Description
type required Either:
  • "type": "device_if"
  • "type": "device_unless"
identifiers required

Target device designation by the following identifiers.
You can examine them in EventViewer > Devices tab.

  • vendor_id
  • product_id
  • location_id
  • is_keyboard
  • is_pointing_device

All identifiers are optional.

description optional A condition description for human.

keyboard_type_if and keyboard_type_unless

{
    "type": "keyboard_type_if",
    "keyboard_types": [
        "ansi",
        "iso"
    ]
}
Name Required Description
type required Either:
  • "type": "keyboard_type_if"
  • "type": "keyboard_type_unless"
keyboard_types required Target keyboard types.
  • ansi
  • iso
  • jis
description optional A condition description for human.

input_source_if and input_source_unless

{
    "type": "input_source_if",
    "input_sources": [
        {
            "language": "language regex",
            "input_source_id": "input source id regex",
            "input_mode_id": "input mode id regex"
        },
        {
            "language": "language regex",
            "input_source_id": "input source id regex",
            "input_mode_id": "input mode id regex"
        },
        ...
    ]
}
Name Required Description
type required Either:
  • "type": "input_source_if"
  • "type": "input_source_unless"
input_sources required

Target input source definitions.
You can find the current input source identifiers by EventViewer > Variables tab.

language, input_source_id and input_mode_id are optional.

description optional A condition description for human.

variable_if and variable_unless

{
    "type": "variable_if",
    "name": "variable name",
    "value": variable value
}
Name Required Description
type required Either:
  • "type": "variable_if"
  • "type": "variable_unless"
name required Target variable name.
value required Target variable value.
description optional A condition description for human.