May 7 '23

Anatomy of a custom keyboard

This is my quick summary and background before talking details of my custom board. I read a fair bit on the way and will try to share the surprises and information gaps I found. There are better and more complete references out there. E.g. Keyboard University.


I’ve only ever used full-size 100% ~104 key boards before. These come with a bulky number pad. I never realised how much extra desk space it consumes, right next to where the mouse could be moving too! Fair warning that some apps like blender become more combersome to use without it.

The next step down is ten key less TKL. These in theory just remove the number pad. I’ve also seen them called 80%, but I’d argue TKL should include the navigation panel and 80% is the step that removes it. TKL sounds ideal to me. Just be careful because many manufaturers still use the TKL label but then remove the nav. panel or totally butcher its layout as well. E.g. up and down aren’t above/below each other or are half height and PgUp/PgDn/Home/End all become one vertical line. Ugh. As a programmer, I have learned strong muscle memory for the all important arrows, home and end keys.

Next to go is the function keys and that navigation panel. This is getting into the realm of compact 60% keyboards. Since I’m making my own keyboard, less keys means less work designing, building and soldering. There are 40% boards and beyond that start drop the number keys, but they require much more fiddly macros and modifier “layers” to be used.

I was totally against the idea of losing the navigation panel. As a programming I probably spend more time moving a cursor, selecting and copy/pasting than typing actual letters. However, after using a moonlander as a stop-gap until I’d finished my custom keyboard I surprised myself with the ease of moving the navigation panel to a separate layer controlled with a modifier. Just like shift gives capital letters and different symbols, I have a modifier that turns I, J, K, L into arrow keys and all the number keys into F* function keys.

Layout, Layers and Macros

The layout is where the keys are. They’re somewhat linked with the size conventions. The most common physical layout is American National Standards Institute ANSI (e.g. ANSI-104). I remember my university had a mix of boards and some had a skinny left shift to make room for a backslash. I think those are International Organization for Standardization ISO layouts. Completely unusable :P.

Among the “alphas” letter keys QWERTY is not the only logical layout. There are also Dvorak and Colemak. It’s common to see these compared based on finger tip distance travelled for typing things. As a programmer I don’t think this is representitive. I’ll say it again, 90% is moving, selecting, copying and pasting. I definitely think there’s some room for optimization there. It’d be interesting to run a key logger to get some data to optimize for. This post about a logkeys fork was rather inspiring.

Keys are commonly staggered rows, where each row is offset by a quarter of a key. I think this comes from typewriters to make room for key arms. Some boards flip this aroud and have a staggered collumner layout. The argument being that fingers bend in that direction and are of different lengths. Then there are ortholinear keyboards which are just a flat grid. In my experience it’s fast to change between them — I miss for a bit and then subconsciously adjust in a few days.

At this point, I have to mention This site allows you to create your own layouts. It takes a little bit to learn, but great to get your ideas on paper, so to speak. There’s also export features for QMK and custom key cap printing, but I ignored those.

When you’re building something from scratch you have complete control over what each individual key maps to. Chances are you’ll be using the open source Quantum Mechanical Keyboard (QMK) firmware too, which is very customizable. I don’t think there are any great conventions here. There are few reddit posts asking for ideas and I think this is most valuable. Everyone will be different, especially given the choice to make a custom keyboard, and it’d be nicer to pick and choose from good things others have tried.

My top picks are:

  • A layer modifier for arrow keys on I, J, K, L. Some people use VIM H, J, K, L arrows, but I never bothered to learn. It’s aguably easier to press the modifier than move your whole hand to a nav panel. Takes some getting used to but worth it.
  • Adding U = Home and O = End to this works OK. Also P = PgUp and ; = PgDn.
  • Using a modifier to change numbers keys into F* function keys. Not only does this avoid the need for function keys, but they’re now easier to reach. I have big hands and I cannot comprehend the Microsoft convention of F3 for “find next” and shift-F3 for “find previous” (gedit‘s use of arrow keys for that is pure genious) but these are now possible to reach.
  • Enter is not used that often. It can also be frustrating to accidentally hit. Moving it to a second layer even though I have a dedicated key available has been useful to me.
  • Curly braces can be their own key in QMK, without pressing shift. I dropped the square and curly braces keys completely and then moved them to a layer at E = {, R = }, D = [ and F = ].
  • You can put keys like Ctrl and Shift next to each other so you can hold them both with one finger, or thumb :).
  • Thumb clusters are amazing. Why in the world is Ctrl, my most used key, the furthest from the middle and given to the second-to-weakest finger.

More ideas…

Shape, Tilt and Tenting

Split keyboards are entirely seprate halves. If you find yourself crossing the center line with either hand, these will take some time getting used to. I found I naturally started to learn to touch type after moving to a split keybaord.

I think anything that isn’t a flat rectangle is “ergonomic”. Split boards are still ergonomic even if flat because you can change the angle to avoid a crook in your wrists. I think a division in halves, rather than being totally separate is ergonomic but not technically split. For me this separation is the most important thing to avoid pain. Flat boards are probably easier to manufacture but I quite like having a bit of a dip in the middle of each hand, around D and K. This might be achievable just by changing keycap heights.

Tenting is when split halves face away from each other, forming a tent shape. You can buy after-mraket tenting kits for split keyboards. You can also 3D print stands for them.

The tilt of the board is how much the keyboard faces towards or away from you. Have you ever noticed the little legs keyboards have at the back that actually raise them up? This seems daft. You have your palms resting on the table and fingers have to angle way back towards your face. Now it’s worth mentioning that there are aruments for a floating hand position, which might work in this case and in general sound healthier than anchoring your palms to the table. However I have years with a lazy habit of resting my wrists on something. I’m not sure if I could get through a full work day and gaming session like that. Backwards tilt is when the keyboard is angled away from you. The MS Natural 4K provided this with a plastic skirt you could fix to the front of the board. Completely usable without. Totally amazing with it.


Most off-the-shelf keyboards use a single membrane sheet with little bumps and conductive pads. When pressed the pads connect terminals on the PCB which closes a circuit and registers a keypress. They’re very cheap to mass produce and I gather very difficult to make for a custom keyboard.

Custom keyboards use individual mechanical switches. They are self-contained momentary buttons. Some people do open them to add lube or dampening mods. The Cherry MX standard is most common but there are others. There are 3-pin “plate mount” and 5-pin “PCB mount” (details here) — they both only have 2 electrical connectors, but also include plastic pins for stability. Switches don’t come with key caps.

“Hot swappable” switches just means that the switches aren’t soldered to the PCB and can be removed with a tool. I bought a cheap off-the-shelf mechanical keyboard just to see if I minded switching from a membrane keyboard. A benefit was since it was hot swappable I could repurpose all the keys and keycaps for my custom board.

There are a lot of different kinds. I’d recommend buying a sampler set or getting “tactile”/”brown” switches to start with. My personal opinions:

  • Tactile/browns just feel natural
  • Speed/coppers are awesome, but also quite loud on the upstroke
  • Clickey/blues are way too loud; I’d prefer the tactility without the sound
  • Linear/reds feel pleasantly smooth and light, but have no activation feedback; not my thing

I bought some Kailh box whites which are good fun to use with modifier keys but don’t always activate exactly where the click is. There’s more play if pressure is on the back of the key compared to the front.

Some switches have in-built LEDs or holes that skinny LEDs can fit in. Many have a hole at the top for PCB-mounted LEDs to shine through and some are made of clear plastic to further help.

Key caps

What is there to say. There’s lot of different shapes, textures and colors. You can even get them custom ordered with your own lettering or arbitrary designs. Obviously per-key lighting only works if the lettering is transparent. Again, the Cherry MX connection between switches and key caps is the most common.

Plate, PCB and Switch Sockets

The plate is a sheet of metal that holds the switches. I guess they’re often laser cut. People get together and make bulk orders to get the cost down. It needs to take the brunt of the force when someone is wrong on the internet or your compiler is giving you annoying errors.

The printed circuit board (PCB) is the board with the electronics that the switches plug into. Given the term “PCB mount” I gather it is possible to forego the plate, but I have no experience there.

You can skip the PCB entirely and solder wires directly to the switches. It’s a fair bit of wiring to do by hand, especially when diodes are involved for multiplexing. I think this is a great idea for prototyping as it’d be much faster to build. You can also buy little plastic MX-compatible Kailh Switch Sockets that can be mounted in 3D printed parts to make the board hot swappable. Finally, you can buy 1x1 key PCBs that include the same switch sockets, some with LEDs and even pre-assembled.


Every keyboard needs to communicate with the PC. This is done with USB and these days there are common protocols/drivers that most devices are compatible. Microcontrollers such as Arduino are unbelievably cheap these days and some (but not all) are able to use the same USB connection they’re programmed with to also appear as another USB device like a keyboard. The QMK firmware does all this for you and has many little convenient features that make it “just work”.

A giant word of caution with regard to features. QMK is big (relatively) and it doesn’t take much to overshoot the limits of program memory on most microcontrollers. For example the Arduino Pro Micro has 32k (28k usable after accounting for the bootloader). It is possible to do a lot of hand coding to fit things in, but if I were to do this again I’d try to aim for something bigger. Maybe something like the STM32F4 with a more powerful ARM Cortex-M4. This is largely because I added a display and per-key RGB, each needing more software enabled to control.


The microcontroller will read switch states by sending an electrical current down a circuit and checking to see if the circuit is closed by a switch. It does this at least hundreds of times per second. You’ll quickly note that microcontrollers only have on the order of 20 general purpose input–output (GPIO) pins and there are more than 20 keys on a keyboard. This problem is solved multiplexing with a key matrix, where you send a signal to a whole row of switches at a time and read the entire column. Diodes are added to avoid feedback and “ghost” keypresses from holding down multiple keys at once. I think this could be extended to charlieplexing, but that’s probably unnecessary.


There is per-key lighting and underglow. It can be RGB or just a single color. See this In-depth explanation of RGB lighting.

Underglow is pretty easy to add with some LED strips. Per-key lighting is a fair bit more fiddly. You can get reverse surface mount LEDs that point down towards the PCB. The light goes through a hole in the PCB, through a hole in the switch and finally through transparent plastic in the keycap. If not using a PCB you can also get very skinny LEDs with legs that could be positioned below or inside the switches. I think some switches even come with in-built LEDs.

Now if you want individually controllable per-key lighting that’s where things get interesting. There are two ways:

  • Individually addressible LEDs. These are actually little integrated circuits using, e.g. WS2812B or SK6812, that listen for RGB values on a data line and then use pulse width modulation (PWM) to change the individual RGB LED brightness. After each gets its RGB value it bridges the input and output to send subsequent signals on to the next LED. When silence is detected on the data line it resets and waits for the next update. These are very convenient. The only downsides are a small power overhead for the IC and if one fails so does the rest of the LEDs in the chain.
  • Multiplexing. Exactly the same as is done for reading the switch states except now for powering LEDs. For RGB this means 3 more matrices. Impossible to do with a single microcontroller, but possible with GPIO extenders. This may save some power and you can choose any LED you want, but it’s a lot more wiring.

One important thing to talk about is power consumption. Every LED on paper consumes 20 milliamps. USB has 500 milliamps to spare and a good 100 or more of that goes to the microcontroller. That leaves 20 LEDs or 6 RGB LEDs. Ridiculous, right? This is the maximum brightness. In practice USB can give a little more without limiting it or triggering over-current protection. I didn’t find any good information about this before my build so my plan was to run everything at minimum brightness and increase it bit by bit. I think there is some danger in suddenly drawing too much USB power even though it should have over-current protection. Also bear in mind many of the current limits on paper are quite high and best to be avoided with a decent margin. With PWM, driving 65 RGB LEDs at 10% brightness and a further 6 indicator LEDs at maximum seemed to just work. I tested a little above this just to make sure I wasn’t close to any limits. At least no failures yet. You can buy tiny surface mount LEDs with lower power consumption but I couldn’t find any in an individually addressible package. Adding a big capacitor is important otherwise a sudden change in power draw from animations can brown out the microcontroller.


QMK can give some audio feedback with a buzzer. Note that only some pins on the microcontroller can control a buzzer! I found this out the hard way and was lucky I had one unused pin to rewire it to.

QMK has support for inexpensive 128x32 pixel displays. Handy for debugging your QMK code changes but not vital to the role of a keyboard. I did try some animation. My arduino wasn’t up to the task of making full image rewrites in a timely manner, but is fine for a few pixels here and there.

Some people add rotary encoders, e.g. a knob with a push button.

My first build


There are no comments yet.