Skip to main content

Karabiner-Elements

Karabiner-Elements is a very powerful keyboard customizer, however, the JSON config format is hard to use for complex mappings. So I created a tool, karabiner.ts, to write the config in TypeScript with strong-typing and abstracted features.

brew install --cask karabiner-elements


One excellent starter on the Apple keyboard is to map (caps_lock) to Hyper (⌘⌥⌃⇧) modifier when press-and-hold (and still work as when tap):

map('⇪').toHyper().toIfAlone('⇪') // Or map('caps_lock').toHyper().toIfAlone('caps_lock')

Then you can bind (Hyper) + keys to Raycast commands, or to switch apps like:

  • Hyper+v -> Paste with Raycast Clipboard History
  • Hyper+f -> Switch to Finder app

If you are a Vim user, you can map it to instead when tapped:

map('⇪').toHyper().toIfAlone('⎋') // Or map('caps_lock').toHyper().toIfAlone('escape')

If you'd like to keep the key, you can bind it to ⇧+⇪:

map('⇪').toHyper().toIfAlone('⎋') // Or map('caps_lock').toHyper().toIfAlone('escape')

map('⇪', '⇧').to('⇪') // Or map('caps_lock', 'shift').to('caps_lock')
  • Tap ->
  • Held -> Hyper (⌘⌥⌃⇧)
  • ⇧ + ⇪ ->
    • (without ) -> (caps_lock off)

Now, imagine you can make every key on the keyboard a layer, which when pressed and held, allow every other key on the keyboard to do something like:

  • Launch or switch to an app
  • Move or resize the current app window
  • Run anything on the computer

👨‍💻 My config is here. I will add more details on how I use it later.