# Putting your Keyboard on Steroids with Karabiner Elements

Original: https://swyx.io/writing/karabiner_lindquist
Published: 2020-08-28

> I did a livestream with John Lindquist from Egghead.io today, and he blew my mind on how much mileage you can get out of your keyboard!

Today [I joined John Lindquist's Twitch stream to learn Karabiner Elements](https://www.twitch.tv/videos/723328200)! 

My interest stems from 2 directions:

- [my recent RSI explorations](https://dev.to/swyx/notes-on-rsi-for-developers-who-don-t-have-it-yet-239n)
- a general interest in productivity and automation - I have heard a great deal from folks like Wes Bos how much TextExpander and Alfred help them in productivity, and I suspect I am not taking as full advantage of these tools as I should be.

Friends like [Brandon Bayer](https://twitter.com/flybayer/status/1288610907367514113) use Karabiner to prevent bad (for RSI) key combinations, and both John and [Vadim](https://twitter.com/swyx/status/1274054230911803392) use it to do "Home Row Computing".

## What is Karabiner Elements?

[On its website](https://karabiner-elements.pqrs.org/), it describes itself as "A powerful and stable keyboard customizer for macOS". It is [free and open source](https://github.com/pqrs-org/Karabiner-Elements). 

I have also heard it called a "key remapper", but I don't think that describes the full range of what it does, because "map from A to B" is just the bare minimum of the possibility.

## Setting up Karabiner and Goku

After [downloading](https://karabiner-elements.pqrs.org/), the next move was to set up [Goku](https://github.com/yqrashawn/GokuRakuJoudo). Karabiner has a verbose JSON DSL - Goku lets you write a terser Clojure based EDN format that compiles to that JSON.

```bash
brew install yqrashawn/goku/goku
cd /Users/yourusername/.config
touch karabiner/karabiner.json
touch karabiner.edn
# prepopulate the edn with something from https://github.com/yqrashawn/GokuRakuJoudo/blob/master/tutorial.md
goku
```

This will give you something to start with.

## The EDN language

EDN is a dialect of Clojure. This is basic EDN:

```clojure
{:main [
  {:des "hello world"
   ; comments use semicolons
   :rules [
      [:a :b] ; map a key to b key
   ]}
]}
```

We didnt find the EDN VSCode Extension formatter to be very good, so we just manually formatted the file ourselves.

The array syntax is good for setting up multiple rules:

```clojure
{:main [
  {:des "mapping some keys to the other"
   :rules [
      [:a :b] 
      [:c :d] 
      [:e :f] 
      [:g :h] 
   ]}
  {:des "combination keys"
   :rules [
      ; map "shift+spacebar" to " = "
      [{:key :spacebar :modi :left_shift} [:spacebar :equal_sign :spacebar]]
   ]}
]}
```

You can create layers to put Karabiner into modes:

```clojure
{
     :layers {
        ; implement caps lock mode
        :caps_mode {:key :caps_lock :alone {:key :escape}}}
        ; implement vs code mode
        :applications {
            :code ["com.microsoft.VSCode"]
        }    
     :main [
    {:des "capslock layer"
    :rules [
        :caps_mode
            ; VIM MODE - hold caps and AJKL
            ; home row computing
            [:##h :left_arrow] ; even with f, still do left arrow
            [:##k :up_arrow]
            [:##j :down_arrow]
            [:##l :right_arrow]
            [:##f :left_option]
            [:##d :left_shift]
            ]}
    {:des "these only work when you are inside vscode"
    :rules [ 
        :code
            [:p :m] ; remap p to m INSIDE VSCODE
    ]}
     ]
}
```

You can even enable a [multitouch extension](https://karabiner-elements.pqrs.org/docs/manual/misc/multitouch-extension/) to switch modes based on how many fingers you have on the touchpad!

```clojure
{:des "trackpad2"
:rules [ 
    ; 2 fingers down
    [:condi ["multitouch_extension_finger_count_total" 2]]
        [:f :button2] ; 
        [:v [:button1 :!Cv]] ; go around and paste
        ; idea: g for cmd + click
]}
```

## More

To see an expert's edn file, see:

- https://github.com/nikitavoloboev/dotfiles/blob/master/karabiner/karabiner.edn
- search github: https://github.com/search?l=&q=filename%3Akarabiner.edn&type=Code

other ideas for things you can do:

- https://stevelosh.com/blog/2012/10/a-modern-space-cadet/#s15-better-shifting
- http://vadimpleshkov.me/notes/all/remapping-arrows/
- [ensure consistent keyboard shortcuts in different apps](https://twitter.com/johnlindquist/status/1298317208435585024?s=20)
