~/.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"
        }
    ]
}

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
                }
            }
        ]
    }
}

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_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_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,
            ...
        ]
    }
}
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)

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

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

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.