Skip to content

Instantly share code, notes, and snippets.

@JoeArauzo
Last active September 19, 2025 11:40
Show Gist options
  • Save JoeArauzo/0c65db3c4c488a007124f81246dc4440 to your computer and use it in GitHub Desktop.
Save JoeArauzo/0c65db3c4c488a007124f81246dc4440 to your computer and use it in GitHub Desktop.
Karabiner Elements Shift to Caps Lock Toggle

Shift Key to Caps Lock Toggle for Karabiner Elements

Overview

A Karabiner Elements Complex Modification that allows you to toggle Caps Lock by tapping either Shift key, while preserving normal Shift functionality when holding the keys down. This is particularly useful when you have remapped your Caps Lock key to other functions (like Escape or Hyper key) but still need occasional Caps Lock functionality.

Features

  • Tap either Shift key: Toggles Caps Lock on/off

  • Hold either Shift key: Functions as normal Shift modifier

  • Immediate Shift response: Works instantly when combined with other keys

  • Configurable timing: 250ms threshold between tap and hold behavior

Requirements

  • macOS with Karabiner Elements installed

  • Karabiner Elements version 13.0.0 or later (for hold_down_milliseconds support)

Installation

  1. Open Karabiner ElementsComplex Modifications tab

  2. Click Add your own rule button

  3. Copy and paste the JSON configuration below into the editor

  4. Click Save button

  5. Enable the rule by clicking the Enable button

Method 2: Manual File Installation

  1. Save the complete JSON (with title and rules wrapper) to a .json file

  2. Place the file in ~/.config/karabiner/assets/complex_modifications/

  3. Open Karabiner Elements → Complex Modifications → Add predefined rule

  4. Import and enable your custom rule

Configuration

For GUI Installation (Add Your Own Rule)

{
  "description": "Tap Shift for Caps Lock, hold for normal Shift",
  "manipulators": [
    {
      "type": "basic",
      "from": {
        "key_code": "left_shift",
        "modifiers": {
          "optional": ["any"]
        }
      },
      "to": [
        {
          "key_code": "left_shift",
          "lazy": true
        }
      ],
      "to_if_alone": [
        {
          "key_code": "caps_lock",
          "hold_down_milliseconds": 200
        }
      ],
      "to_if_held_down": [
        {
          "key_code": "right_shift"
        }
      ],
      "parameters": {
        "basic.to_if_alone_timeout_milliseconds": 250,
        "basic.to_if_held_down_threshold_milliseconds": 250
      }
    },
    {
      "type": "basic",
      "from": {
        "key_code": "right_shift",
        "modifiers": {
          "optional": ["any"]
        }
      },
      "to": [
        {
          "key_code": "right_shift",
          "lazy": true
        }
      ],
      "to_if_alone": [
        {
          "key_code": "caps_lock",
          "hold_down_milliseconds": 200
        }
      ],
      "to_if_held_down": [
        {
          "key_code": "right_shift"
        }
      ],
      "parameters": {
        "basic.to_if_alone_timeout_milliseconds": 250,
        "basic.to_if_held_down_threshold_milliseconds": 250
      }
    }
  ]
}

For File Installation (Complete JSON)

{
  "title": "Shift to Caps Lock Toggle",
  "rules": [
    {
      "description": "Tap Shift for Caps Lock, hold for normal Shift",
      "manipulators": [
        {
          "type": "basic",
          "from": {
            "key_code": "left_shift",
            "modifiers": {
              "optional": ["any"]
            }
          },
          "to": [
            {
              "key_code": "left_shift",
              "lazy": true
            }
          ],
          "to_if_alone": [
            {
              "key_code": "caps_lock",
              "hold_down_milliseconds": 200
            }
          ],
          "to_if_held_down": [
            {
              "key_code": "left_shift"
            }
          ],
          "parameters": {
            "basic.to_if_alone_timeout_milliseconds": 250,
            "basic.to_if_held_down_threshold_milliseconds": 250
          }
        },
        {
          "type": "basic",
          "from": {
            "key_code": "right_shift",
            "modifiers": {
              "optional": ["any"]
            }
          },
          "to": [
            {
              "key_code": "right_shift",
              "lazy": true
            }
          ],
          "to_if_alone": [
            {
              "key_code": "caps_lock",
              "hold_down_milliseconds": 200
            }
          ],
          "to_if_held_down": [
            {
              "key_code": "right_shift"
            }
          ],
          "parameters": {
            "basic.to_if_alone_timeout_milliseconds": 250,
            "basic.to_if_held_down_threshold_milliseconds": 250
          }
        }
      ]
    }
  ]
}

How It Works

Technical Details

The modification uses several Karabiner Elements features:

lazy: true

Prevents the Shift modifier from being sent immediately when pressed, allowing the tap/hold detection to work properly.

to_if_alone

Triggered when a Shift key is pressed and released quickly (under 250ms threshold).

to_if_held_down

Triggered when a Shift key is held down for longer than the threshold (250ms).

hold_down_milliseconds: 200

Critical parameter that ensures the caps_lock key event is held down long enough for macOS to register the state change.

optional: ["any"]

Allows the modification to work regardless of other modifier keys being pressed.

Timing Parameters

basic.to_if_alone_timeout_milliseconds: 250

Maximum time for a key press to be considered a "tap" rather than a "hold".

basic.to_if_held_down_threshold_milliseconds: 250

Minimum time a key must be held before triggering the hold behavior.

Customization

Adjusting Timing

You can modify the timing parameters to suit your preferences:

  • Shorter timeout (e.g., 150ms): More responsive but may cause accidental caps lock activation

  • Longer timeout (e.g., 400ms): Less sensitive but may feel sluggish

Alternative Behaviors

To modify the behavior, you can change:

  • hold_down_milliseconds: Adjust how long caps_lock is held (affects reliability)

  • key_code: Change which keys trigger the behavior

  • Add conditions: Restrict to specific applications or devices

Troubleshooting

Caps Lock Doesn’t Toggle

If quick taps don’t toggle Caps Lock:

  1. Verify hold_down_milliseconds is set to 200 or higher

  2. Check that you’re using Karabiner Elements 13.0.0 or later

  3. Ensure the "Disable the accidental keystroke prevention of Caps Lock" rule is enabled if you experience delays

Shift Not Working as Modifier

If holding Shift doesn’t work for typing capitals:

  1. Verify lazy: true is present in the to array

  2. Check that to_if_held_down contains the correct shift key

  3. Ensure timing parameters aren’t too aggressive

JSON Import Errors

If you encounter JSON parsing errors:

  1. Verify you’re using the correct JSON format for your installation method

  2. Check that all brackets, braces, and quotes are properly matched

  3. Ensure no trailing commas are present

Use Cases

  • Users who have remapped Caps Lock to Escape (common in Vim workflows)

  • Users with Caps Lock mapped to Hyper key or other modifiers

  • Anyone who wants occasional Caps Lock access without dedicated key

  • Touch typists who prefer not to move hands to access Caps Lock

Compatibility

Works With

  • All macOS versions supported by Karabiner Elements

  • External and built-in keyboards

  • Other Karabiner Elements modifications (when properly configured)

  • Vim Mode Plus and similar applications

Potential Conflicts

  • Other modifications that also use Shift keys

  • System-level keyboard shortcuts that use Shift

  • Applications with custom Shift key handling

License

This configuration is released under the MIT License. Use and modify freely.


Created for Karabiner Elements community.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment