A reliable fix for macOS's buggy "use Caps Lock to switch input source" feature.
macOS has a built-in option to switch keyboard input source (layout) with the Caps Lock key. It is unreliable: if you press Caps Lock while typing fast (key rollover), the switch is frequently dropped. It only registers consistently if you stop typing and press the key deliberately. This is a long-standing, widely reported macOS bug, not a configuration mistake.
- Remap the physical Caps Lock key to the otherwise-unused F18 key, at
the HID (hardware input) layer, using the built-in
hidutiltool. - Bind macOS's normal keyboard-shortcut system ("Select the previous input source") to F18 instead of to Caps Lock directly.
Ordinary keyboard shortcuts don't go through the same debounce/hold logic that the native Caps-Lock-specific switcher uses, so once Caps Lock is reporting itself as F18, the switch fires reliably every time, even mid fast typing.
As a side effect, Caps Lock's native capitalization/lock behavior is also fully disabled, since macOS no longer sees a Caps Lock press at all -- only an F18 press. No separate step is needed to turn off "real" Caps Lock.
- macOS with
hidutil(present on every modern macOS install, no third-party software required). - No admin/root password needed -- everything runs in user space via a per-user LaunchAgent.
git clone https://github.com/sipandk-art/capslock-f18-switcher.git
cd capslock-f18-switcher
./install.shThen finish two manual steps in System Settings (there is no scriptable API for these, they must be set through the GUI):
- System Settings → Keyboard → Keyboard Shortcuts... → Input Sources → enable "Select the previous input source" → click its shortcut field → press the physical Caps Lock key (it will be recorded as F18).
- Make sure at least two input sources are added under System Settings → Keyboard → Input Sources, otherwise there is nothing to switch between.
./uninstall.shThis stops and removes the LaunchAgent and clears the HID remap. The shortcut binding created in step 1 above is a separate, native macOS setting and is not touched by this script -- remove or reassign it manually in System Settings if you want it gone too.
Check System Settings → Keyboard → Modifier Keys. If "Caps Lock key" is set to "No Action", the physical key's event is suppressed before it ever reaches the HID remap table, so the F18 remap never has a chance to apply. This setting is commonly left behind by a previous Karabiner-Elements installation. Set it back to the default "Caps Lock" role (or click "Restore Defaults") and the fix will start working immediately.
Confirm the LaunchAgent is actually loaded:
launchctl list | grep capslock2f18If nothing prints, re-run ./install.sh.
hidutil property --set '{"UserKeyMapping": [...]}'rewrites the USB HID usage-code map system-wide: the physical Caps Lock key (usage0x700000039) is reported to the rest of the system as F18 (usage0x70000006D) instead of its own usage code.- This mapping lives only in memory and resets on every reboot, so
install.shalso writes and loads a LaunchAgent (~/Library/LaunchAgents/com.user.capslock2f18.plist) that reapplies the samehidutilcommand automatically at every login. - macOS's general keyboard-shortcut system (used for "Select the previous input source") does not share the fast-typing/debounce bug that the dedicated native Caps-Lock-switch feature has, so once Caps Lock is reporting as F18, binding the shortcut to F18 makes the switch reliable.