DeskFighter

low-key photo of keyboard with narrow depth of field

August 2026

What this article is about

How I designed and built a custom mechanical keyboard (not a kit).

I planned to write this in the form of a tutorial, thinking if I was able to acquire the necessary skills to build a keyboard, anyone can do it. While I believe that's true, it's not realistic for someone who has yet to learn the basics of product design, digital electronics, PCB design, soldering, CAD, 3D printing and building firmware, to build a keyboard as a first project. So this is more of a design journal with tips for other aspiring keyboard builders.

If you're short on time or attention, you can browse through the gallery and read the image captions.

I'm an industrial designer by education and the goals and design principles, I've set for myself, reflect that:

The journey

Motivation

Layout and features

screenshot of the keyboard layout in Figma

I used Figma to work out which features I wanted my keyboard to have and how to arrange everything.

I created frames with auto layouts to arrange keys in rows and columns. It's perfect to get consistent spacing, which can be adjusted interactively with instant feedback. Keys can be moved around by drag and drop.

I created the different key types (1u, 2u, with LED indicator) as components, so they stay in sync and global adjustments are easy to make.

Overall it's a very efficient way to work out the layout, making constant adjustments while keeping everything clean and orderly. Of course it's also convenient to try out colors and fonts for labeling. Icons can quickly be added using the Material Icons font.

photo of keyboard layout paper printout

Once I was happy with the layout, I printed it on paper, at actual size, so I could put my hands on it and give it a sanity check.

What I came up with

Construction

Since the PCB will be visible, I have to think about its appearance. Luckily there are quite a few things to tweak:

Shopping for parts

photo of key sampler

To find out which keys I like, I bought a key sampler with Kailh Choc V2 low profile switches. Decided to use the red ones (linear).

I really liked the keycaps that came with my sampler kit (Tai-Hao low profile, also called THT). They look nice and I can feel the center of the key, when touch typing. I decided I don't want flat keycaps anymore.

Then things got annoying. My naive expectation was, that there is a huge ecosystem of parts for building custom mechanical keyboards, so it would be easy to find exactly what I want. The former part is true, but my conclusion was wrong. Once you decide on certain parts to use, your options shrink drastically, because everything needs to fit together. Deviate from "the common way" to build a keyboard — e.g. by using an "exotic" layout, low profile keys or not having a faceplate — and it gets even more extreme. While these limitations are understandable, they go against the very reason for building a custom keyboard. If you want a regular keyboard, you can just buy one.

After many frustrating hours of browsing shops and figuring out my options, I came up with the following compromises:

Along the way I bought two sets of unsuitable stabilizers (my mistake) and a full set of Kailh Choc V2 switches, which were an older, slightly less nice version than the one I tested before (from a different shop). Come on Kailh — if you modify your "V2" switches, call the new ones "V3".

This was the only part of the project I disliked, and I almost gave up.

CAD and 3D printing

I used FreeCAD to keep this project open for others to modify. It has many UI/UX warts, but I like the relatively quick startup and easy import/export of different file formats, which came in very handy.

Keycaps

screenshot of 2u keycap in FreeCAD

I designed the keycaps to look similar to the THT keycaps, except with a flat top. The flat top avoids the typical layer lines that 3D prints have, which can be felt and seen and which collect dirt and are impossible to clean.

I created 1u and 2u keycaps in separate files and duplicated them in a grid as many times as I needed.

screenshot of key labels in Affinity

Then I created the labels in Affinity (Inkscape or any other vector illustration program would work too). This gave me full control over font and icon styling. I used Futura and material icons.

screenshot of 1u keycaps with labels in FreeCAD

I aligned them in exactly the same grid as I had in FreeCAD, exported them all at once in SVG format and imported that in FreeCAD. A simple extrusion of 0.8 mm and the labels are done.

screenshot of keycaps in Bambu Studio

I found the STEP format ideal to export the parts to be printed. I could export the keycaps and labels together in one file and the slicer correctly loaded that as one object with two parts (keycaps and labels). I could then assign black PLA to the keycaps and white PLA to the labels. The slicing worked as expected and didn't complain about the intersecting objects. Obviously this requires a 3D printer which can change materials automatically.

photo of 3D printed keycaps, still on build plate

Some tips if you try the same:

Feet

photo of 3D printed feet with heat set inserts and rubber pads

I made very simple, cylindrical feet, with a hole for M2 heat-set inserts, and put some self-adhesive rubber pads on them.

By varying the length of the feet at the front and back of the keyboard, I can adjust its height and angle.

PCB design

Matrix layout and ghosting

screenshot of spreadsheet with keyboard matrix

To reduce the number of pins the microcontroller needs, the key switches are arranged in a grid, so that each switch connects a specific column with a specific row when pressed. Each row and each column is connected to one I/O pin. The microcontroller continuously scans this matrix by activating one column at a time and reading all rows.

A drawback of this design is that the microcontroller can detect false keypresses under certain circumstances. If three keys are pressed simultaneously, which form an L-shape on the matrix, the microcontroller will register the key in the fourth corner of the imaginary rectangle as also pressed, even if it isn't — a ghost. That is unless the key in the corner of the L-shape has a diode in series to prevent reverse current flow.

The brute force approach to this problem is to add a diode to every single key. That's fine if components are placed by a pick and place machine (diodes are cheap), but I wasn't looking forward to soldering 91 diodes by hand.

To minimize the chance of ghosting, I've arranged the common combo-keys (shift, ctrl, alt, gui) in a single row and gave them diodes. All other keys have unpopulated solder pads with a copper track in between. This way I have to solder only 8 diodes instead of 91. If I encounter a ghosting problem in daily use, I can cut the track and put in a diode for the problematic key.

To plan the matrix layout, I found a spreadsheet very convenient. It's easy to drag cells around to make changes, conditional formatting helps visualizing different types of keys, formulas can give me all relevant stats — for example how many keys I need to buy and how many I/O pins the microcontroller needs for the matrix.

Electronic parts selection

photo of electronic components on table

I picked an STM32 microcontroller that works with the popular open source keyboard firmware QMK and has plenty of memory and flash storage to use some of the fancy features that QMK offers.

Because I want the top side of the PCB to look clean, I had to find a USB-C connector which does not protrude to the other side. I found one which requires just two 0.7 mm holes in the PCB, which are barely visible.

Rotary encoders are typically very tall. I needed to find one which would go well with my low profile keys. I found one with 20 clicks per rotation, which feels about right. It takes 16 clicks to go from zero to max volume on my OS.

The rest of the parts are nothing special at all. You can find the full list at DigiKey.

Schematic and PCB layout

screenshot of schematic in KiCad

I used KiCad, which was a pretty good experience.

For the USB-C connector and ICs, I mostly followed the recommendations in the datasheets and application notes. I routed matrix rows and columns on opposite layers. When selecting footprints, I made sure to use the variants with the suffix "handsolder" — those have slightly larger pads.

screenshot of routed PCB in KiCad

A word about 3D models

screenshot of kicad 3d viewer with keyboard pcb

KiCad comes with a 3D viewer, which shows the current state of the PCB you're working on, including 3D models of all the parts.

Common parts, which are included in KiCad, already come with 3D models. For the few parts I had to add, I made sure to download 3D models. This turned out to be very helpful. By looking at the 3D visualization, instead of the rather abstract 2D layers, I caught many silly mistakes early.

I found a very nice model of the Kailh Choc V2 switches and some stabilizers, made by GitHub user koktoh. I used FreeCAD to remove the third pin from the switch, because the new version, which I use, has only two. In KiCad's footprint editor, where 3D models are added, I also added the model of my keycaps on top of the switches. This was trivial, because the position of each 3D model can be adjusted individually.

For the rotary encoder and USB-C connector I downloaded footprints and 3D models from DigiKey, respectively the manufacturer.

I also imported the 3D model of the rotary encoder into FreeCAD, to design a cap for it. That made it easy to get a perfect fit, without having to measure any dimensions on the real part.

For the mounting-holes in the PCB, I added the 3D model of the foot, including the M2 screw.

rendering of the keyboard including keys, keycaps and USB wire

The 3D model of the PCB, with all parts, can be exported and opened in FreeCAD. While not necessary in my case, this is invaluable if you need to design an enclosure, which fits snugly around the PCB.

Instead, I imported the PCB into Blender, for a quick visualization — just to get excited about the awesome keyboard I would soon have on my desk.

MacroPad

photo of macro pad

Before designing the keyboard PCB, to avoid expensive mistakes, I built a small "macro pad" with all the features of the big keyboard, but in a minimal footprint: a rotary encoder, a key with LED, 4 keys connected in a matrix to test anti-ghosting diodes, a 2u key with stabilizer, the same microcontroller that I use for the big keyboard.

This was also an opportunity to check text sizes, line widths and the PCB quality.

I had to reduce the holes and cutouts for the switches and stabilizers a bit, for a better fit. I also increased the pad sizes for the USB-C connector for easier hand soldering. Lastly I reduced the brightness of the USB power indicator LED by giving it a higher value resistor. Otherwise everything worked as expected.

photo of PCBs with different quality black soldermask

I ordered MacroPad PCBs from PCBWay and JLCPCB. PCBWay offers matte black soldermask, JLCPCB has only semi-glossy black. The "matte black" soldermask (right) I would call "dark gray". The semi-glossy one (middle) is a bit darker, but of course more glossy. Both have a slightly blue tint. They don't look as nice as the PCB on the left.

Get it made

I would have preferred the matte soldermask from PCBWay, but JLCPCB offers the large keyboard PCB much cheaper ($ 24 vs. $ 125 for 5 PCBs) — therefore I went with semi-glossy black.

photo of DeskFighter PCBs, front and back

To my surprise, I received very nice looking PCBs. The soldermask is a bit more glossy than that on the macropad, but it's a beautiful black and the HASL surface treatment is as good as it gets. I'm not sure why this is — maybe these were produced in a different facility. Either way, I'm happy about it.

With the stated goal of using automated manufacturing, I should of course have ordered PCB assembly as well. I actually tried, but JLCPCB's process of parts assignment and positioning was very buggy and frustrating. The price was not very attractive either, because many of the parts were in the "extended" category, for which an extra charge was applied. On top of that I would have had to pay VAT and a € 20 processing fee on import, which get waived for shipments below € 60.

Firmware

After soldering the SMD parts on the bottom, but before finishing the assembly, I wanted to test if the board even works. After all, I could have messed up the design or there might be a manufacturing issue.

screenshot of terminal while writing firmware to microcontroller

I followed QMK's documentation to configure, build and flash the firmware. I already experimented with this when I built the MacroPad and have prepared the configuration for the keyboard.

photo of DeskFighter PCB with soldered SMD components and red power LED lit

I used tweezers to simulate key presses. Unfortunately none of the keys on column 3 worked, while those on column 8 triggered column 3 as well. Of course I thought I messed up the PCB design or had some solder bridges. But continuity-testing with the multimeter found no problem.

Then I checked the microcontroller datasheet for info about the I/O pins in question. A footnote described some condition when an unwanted pull-down resistor would get activated on my column 3 pin if the column 8 pin was high on startup (a feature intended for dead battery detection).

Luckily I was able to disable this functionality in the QMK configuration. After that, all keys worked and I was very relieved.

Assembly

photo of PCB with all keys soldered

Soldering the rest of the parts was a bit of a chore. Fortunately the switches are through hole parts, which can be soldered efficiently without a microscope.

The rest of the assembly — stabilizers, feet, keycaps — was quite enjoyable. A bit like playing with LEGO as a kid.

photo of PCB with black painted edge

As a final touch, I used a waterproof marker to paint the edge of the PCB black.

I know, I said no post-processing, but this wasn't much work and well worth the effort.

Using it

photo of keyboard on desk

After a few days of using it, these are my impressions:

I'm very happy with the result. It looks and feels great, so I consider this project a success.

BOM and costs

I have no affiliation with any of the mentioned shops and manufacturers. There are only links to shops that I've had a good experience with.

Item Quantity Price Shipping
Keebart
Switch tester (Kailh Choc V2) with blank keycaps 1 € 15.38 € 8.90
Switches (Kailh Choc V2 Red) 100 € 41.20 € 8.90
THT keycaps blank 50 € 18.90
THT keycaps with dot 10 € 4.96
THT keycaps with tactile marker 2 € 1.00 € 8.90
Max Gaming
Durock V3 plate-mounted stabilizer set 1 € 11.50 € 8.00
DigiKey
Various items, quantities for more than one keyboard € ~58.00 1 € 0.00
JLCPCB
DeskFighter PCB 5 € 20.85 2 € 11.26
MacroPad PCB (optional) 5 € 5.46 2 € 15.62
PCBWay
MacroPad PCB (optional) 5 € 17.34 € 25.00
CNC Kitchen
M2 heat-set inserts 100 € 8.67
Installation tip set C245 (optional) 1 € 24.94 € 9.76
AliExpress
M2 × 5 mm screws, black, Torx 50 € 1.47 € 2.00
Rubber feet, 8 mm × 3 mm, self-adhesive 70 € 2.00 € 2.00
€ 231.67 € 100.34

1 Ordered additional products to get free shipping.

2 Applied coupons to reduce shipping costs.

As you can see, it wasn't cheap. A high quality mechanical keyboard, with enclosure, can be bought for around € 200 (prices vary wildly). However, I now have a keyboard that's tailored to my preferences, which I can't buy anywhere.

Mistakes

Things I've bought, but shouldn't have:

But wait…

I want to use something from this project!

Here are the files:
https://github.com/swonkie/DeskFighter

Licensed under CERN-OHL-S-2.0.

If you want to contact me: swonkie (at) pm.me

Why DeskFighter?
It's a nod to "naked" sport bikes, often called Streetfighter.

How much does it weigh?

308 g (10.86 oz).