Split-keyboard ergonomics on a stock MacBook, in one Karabiner-Elements config. The right hand moves a column over, the home row becomes modifiers and four hold layers, and 30 keys you should stop reaching for are switched off.
No firmware. No external keyboard. One karabiner.json.
|
This project is sponsored by PCBWay, a one-stop shop for PCB prototyping, assembly, CNC machining and 3D printing. If you want to turn a keymap like this one into a real split board, they are a good place to have it made — see Sponsor below for what they offer. |
The small grey legend in the corner of each cap is what is physically printed on it. The big legend is what the key actually does.
There is also an interactive version — open it and press keys on your own keyboard to light up the matching cap, or hold Space and a layer key to preview a layer live.
Inspired by @getreuer's QMK keymap, which is the reference for what a well-documented personal keymap looks like.
A laptop keyboard has no thumb cluster and no layer keys, so the usual QMK tricks do not port over directly. This config works around that with three moves:
- Everything worth reaching for moves onto the home row. Numbers, symbols and arrows live on hold layers, not on the number row.
- Space and Right Command become gates. Hold either one and the home row turns into modifiers and layer keys. Let go and it is plain letters again — so there are no accidental mod-taps while typing at speed.
- The keys you should stop using are disabled. The number row,
esc,tab,delete, the arrow cluster and the three worst reaches on the alpha block do not do their job any more.
The alphas are Gallium v2, the row-staggered variant of Gallium — which is the right choice here, because a laptop keyboard is a row-staggered keyboard. Gallium v2 exists precisely for boards like this one, rather than the column-staggered splits most alt layouts are tuned for.
Fitting a 3×10 layout onto a MacBook means the top two rows of the right hand
sit one column to the right of where QWERTY puts them, which is what leaves
Y, H and B with nothing to do:
B L D C V J F O U .
N R T S G Y H A E I
Z X Q M W K P , _
That leading Z is Left Shift — the bottom row is one key short of a home
for it, so it moves onto the shift key and the old Z position (physical N)
is disabled too.
Punctuation that is normally shifted moves down to the shift keys themselves:
| Physical key | Types |
|---|---|
| Left Shift | Z |
| Right Shift | ' |
/ |
_ |
| Left Command | space |
| Space | left gate: hold to arm the left hand's special keys, tap does nothing |
| Right Command | right gate: hold to arm the right hand's special keys, tap does nothing |
| Right Option | delete |
| Caps Lock / Return / Left Option | disabled (types HERROPERS) |
Shift + [ |
esc |
Shift + . |
⌥C |
There are two gates, one per side. Hold Space (left gate, left_gate) to arm
the left hand's special keys, or Right Command (right gate, right_gate) to
arm the right hand's. Each gate only arms its own side: while the left gate is
held, the right hand's special keys are plain letters, and the other way round.
Tapping a gate does nothing.
| Home-row key | Physical | Gate | Hold |
|---|---|---|---|
N |
A |
left | Left Shift |
R |
S |
left | Left Option |
T |
D |
left | Left Command |
S |
F |
left | Number layer |
M |
C |
left | Symbol layer, right |
H |
K |
right | Navigation layer |
A |
L |
right | Left Command |
E |
; |
right | Left Option |
I |
' |
right | Right Shift |
G |
G |
left | Left Control |
Y |
J |
right | Left Control |
P |
, |
right | Symbol layer, left |
Command and Option are always the left-hand modifier, whichever side of the board you hold them on.
The gate is the whole trick. Home-row mods normally misfire during fast typing; here they simply do not exist until you ask for them, and only one layer can be active at a time — each layer key is conditioned on the other three being off.
Every hold latches on key-down, so order never matters. All ten of them —
four layers, two Commands, two Options, two Controls — are written the same way: to sets the
modifier or the layer variable the instant the key goes down, to_if_alone
emits the letter if you tap it and press nothing else, to_after_key_up clears
it on release. Hold the layer first or the modifier first; the result is
identical.
This is worth stating because the obvious way to write a layer key — a
to_if_held_down timer, optionally with a to_delayed_action — does not
compose. Both are cancelable by later key events, so whichever hold you started
first wins and the second one silently does nothing. Nothing here uses a timer.
One thing the gate cannot make order-free: it has to be held first. Conditions are evaluated when a key goes down, so a layer or modifier key pressed before its gate sees the gate variable as 0 and just types its letter.
Each layer also borrows some home-row keys for its own glyphs, which shadows the modifier on those keys. One pair always survives:
| Layer (held with) | Modifiers still reachable |
|---|---|
Number — physical F |
Left Command D, Left Option S |
Symbol right — physical C |
Left Command D, Left Option S |
Symbol left — physical , |
Left Command L, Left Option ; |
Navigation — physical K |
Left Command L, Left Option ; |
In every case the surviving pair is on the same hand that holds the layer, which takes some getting used to. The other hand's Command and Option are typing layer glyphs and cannot also be modifiers.
Number — left gate + hold S. Digits sit under the right hand, with ~ on Right
Shift:
7 8 9 F O U .
0 1 2 3 H A E I
4 5 6 ~ K P , _ '
Symbol, left — right gate + hold P. Held by the right hand, typed with the left:
^ * - | B L D C
+ ! / = N R T S
` < > @ Z X Q M
Symbol, right — left gate + hold M. Held by the left hand, typed with the right:
; & $ # F O U .
[ ] ( ) H A E I
: \ % ? P , _ '
Navigation — right gate + hold H. The top row moves the caret one step, the home
row is caps lock tab esc return, and the bottom row moves the caret five at a
time (five key events at 30 ms each):
← ↑ ↓ → B L D C
caps tab esc ⏎ N R T S
←5 ↑5 ↓5 →5 Z X Q M
Thirty keys are booby-trapped. They do not just do nothing — press one and
it types HERROPERS, loudly, in the middle of whatever you were writing:
` 1 2 3 4 5 6 7 8 9 0 - = delete tab ] \
esc control option caps lock return ← → ↑ ↓ and the Y / H / B / N positions.
Every one of them has a home-row replacement:
| Reach | Do this instead |
|---|---|
| Number row | left gate + hold S |
- = [ ] \ and friends |
the two symbol layers |
| Arrow keys | right gate + hold H |
delete |
Right Option |
tab |
right gate + hold H, R |
esc |
Shift + [, or right gate + hold H, T |
return |
right gate + hold H, S |
control / option |
left gate + hold G or right gate + hold J for control; home-row S / ; for option |
It is a blunt instrument and it works. Delete the rule named
Bad-habit trainer once the habit is gone — or keep it forever, nobody is
judging.
| Key | Action |
|---|---|
F3 |
⌘⇧⌃4 — screenshot a region to the clipboard |
F4 |
Raycast (⌥⌃⌘⇧ + a) |
F6 |
Toggle the whole keymap on and off |
⌥ + A |
Raycast |
⌥ + S |
Mouseless |
⌥ + E |
Homerow |
⌥ + T |
esc |
⌥ + J/K/L/; |
AeroSpace window focus (⌥ + h/a/e/i) |
⌥ + F |
AeroSpace shrink window (⌥ + s — resize smart -50) |
⌘⌃⌥⇧ + D |
Mouseless free-click (⌘⌃⌥⇧ + tab) |
F6 runs toggle_profile.sh, which flips
Karabiner between the Default profile and a Disabled profile that contains
nothing but the toggle itself. Handy when someone else needs to use your laptop,
or when you need to type a password into a field that fights you.
Requires Karabiner-Elements.
git clone git@github.com:noodleweapon/splitmac.git
cd splitmac
mkdir -p ~/.config/karabiner
# back up whatever you have now
cp ~/.config/karabiner/karabiner.json ~/.config/karabiner/karabiner.json.bak
cp karabiner/karabiner.json ~/.config/karabiner/karabiner.json
cp karabiner/toggle_profile.sh ~/.config/karabiner/toggle_profile.sh
chmod +x ~/.config/karabiner/toggle_profile.shKarabiner picks the file up as soon as it is written. One path in the config
points at this machine — the F6 toggle script — so edit or drop that rule if
you do not want it.
Warning: this replaces your entire Karabiner config, and the alpha layout means you cannot touch-type on the machine until you learn it. Keep the backup and remember that
F6turns everything off.
Rule order in karabiner.json matters. Karabiner chains manipulators, so each
rule sees the output of the ones above it — the disabled-key rule runs first so
it wins on Y/H/B/N.
The layout data lives in tools/keymap.py and everything
else is generated from it:
python3 tools/render_svg.py # writes img/*.svg
python3 tools/build_html.py # writes keymap.htmlNo dependencies beyond the standard library.
PCBWay sponsors this project. They are a one-stop shop for turning a hardware idea into a physical thing: PCB prototyping and small-batch fabrication, PCB assembly, CNC machining, sheet metal, injection moulding and 3D printing (resin, nylon, and metal), all ordered from one account with an instant online quote.
Why they are a good fit for a keyboard project:
- Cheap, fast prototypes. A handful of 2-layer boards costs a few dollars and ships in days, so a keymap idea can become a real split board without a big commitment.
- One order, every part. Plates, cases and the PCB itself can all come from the same order — CNC-cut aluminium or 3D-printed cases alongside the boards.
- Assembly included. Hand-soldering a hundred hot-swap sockets is optional; PCBWay can populate the boards for you.
- Real humans in support. Every order is checked by an engineer before it goes to fabrication, and the DFM feedback comes back quickly.
If you use them, say hello from splitmac.
- PCBWay for sponsoring the project
- Karabiner-Elements by Takayama Fumihiko
- @getreuer's QMK keymap for the documentation format
- Gallium by GalileoBlues — the alpha layout. This config uses v2, the row-staggered version
MIT