I told myself this was a quick project. A weekend, a soldering iron, a kit of parts, and a keyboard at the end. The soldering was indeed a weekend. The firmware has eaten three weeks and I regret nothing, because that turned out to be the actually interesting part.
The build itself is approachable if you can solder, and forgiving if you can't, mostly. A 60 percent PCB, a plate, a case, a set of switches, and a bag of keycaps. The switches push through the plate and into the PCB, and you solder two pins each. Sixty-one keys, a hundred and twenty-two joints, and a podcast. The only genuine skill is not cooking the PCB and not bridging adjacent pads, and a flux pen plus a decent tip handles most of that.
the part nobody warns you about
Once it's assembled and the continuity tester says you haven't made a smoking mistake, you flash firmware. I went with QMK, because it's open, it's well documented, and it runs on a vast range of boards. And this is where a keyboard stops being a keyboard and becomes a tiny programmable computer that happens to have switches attached.
The mental model clicked once I understood layers. A keyboard isn't a flat map of switch to character. It's a stack of maps, and you move between them with modifier-style keys. My base layer is ordinary QWERTY. Hold a key I've designated as the layer key and the whole board transforms: the right hand becomes arrow keys and navigation, the number row becomes function keys, and I never move my hands to reach for them. On a 60 percent board with no dedicated arrows or function row, this isn't a luxury, it's the thing that makes the board usable at all.
You define it all in a C file, a keymap.c, as nested arrays:
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BASE] = LAYOUT(
KC_ESC, KC_Q, KC_W, KC_E, /* ... */ KC_BSPC,
MO(_FN), KC_A, KC_S, KC_D, /* ... */ KC_ENT,
/* ... */
),
[_FN] = LAYOUT(
KC_GRV, KC_1, KC_2, KC_3, /* ... */ KC_DEL,
_______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, /* ... */
/* ... */
),
};
MO(_FN) means "momentarily activate the function layer whilst held". _______ means "fall through to whatever the lower layer does here". Compile, flash, test, swear gently, repeat. The loop is fast and the feedback is immediate, which is dangerously satisfying.
the rabbit holes
QMK gives you far more than layers, and each feature is its own afternoon. Tap-dance lets one key do different things on single, double or held presses. Tap-hold sends one keycode when tapped and acts as a modifier when held, so my Escape key is also Control when I lean on it, which after a week I cannot live without. There's a per-key debounce, mod-tap, combos where pressing two keys together emits a third, and macros for the things you type so often it's worth the firmware space.
The temptation is to add everything. I did, briefly, and ended up with a board so clever I couldn't remember how to type a bracket. The discipline, which I'm still learning, is to add a feature, live with it for a few days, and rip it out if your hands haven't internalised it. Muscle memory is the real constraint, not flash size. A keymap you have to think about is worse than a plain one you don't.
was it worth it
Yes, plainly. Not because a custom keyboard types faster, it doesn't, but because the firmware is genuinely good software and tweaking it scratches exactly the itch that makes me enjoy this job. There's something honest about a tool you can open, understand top to bottom, and reshape to fit your hands. The hardware is a solved problem you can buy. The firmware is a hobby with no natural end, and I mean that as praise.
If you're thinking about it: buy a hot-swap board for your first one so you can change switches without a soldering iron, learn the layer model before you touch the fancy features, and budget the firmware time honestly. It's not a weekend. It's a slow, pleasant erosion of your free evenings, and the keyboard at the end is genuinely yours.