QMK firmware: a tmk derivative whose build depends on the qmk CLI
Open-source keyboard firmware for Atmel AVR and Arm USB families
At a glance
- What is it?
- QMK is C firmware for Atmel AVR and Arm USB keyboard controllers, grown out of tmk_keyboard and organized as a Makefile plus a pile of per-board directories. Reading the top-level Makefile shows the real constraints: the build shells out to an external CLI before it compiles anything, takes its version from a git tag rather than a release, and refuses to run in parallel.
- Who is it for?
- QMK fits someone who owns a supported board and wants their layers, macros, and tapping behavior under their own control. It does not fit someone who wants a packaged installer or a downloadable release artifact, because the repository publishes no GitHub releases and the version banner comes from a git tag lookup that disappears the moment the tree is not a work tree.
- Can I use it commercially?
- Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.
Star history
- qmk/qmk_firmware20,810 ★ · +96
| Repository | 2026-09-21 | 2026-11-13 |
|---|---|---|
| qmk/qmk_firmware | 20.7k | 20.8k |
96 Stars in the last 53 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
tmk_core/ next to quantum/ is the receipt of where this came from
QMK describes itself as keyboard firmware based on the tmk_keyboard firmware, with added features for Atmel AVR and ARM controllers, and names the OLKB product line, the ErgoDox EZ, and the Clueboard product line as the specific targets. The top-level tree keeps that lineage visible rather than merging it away: `tmk_core/` sits beside `quantum/`, `builddefs/`, `platforms/`, and `drivers/`, so the inherited core and the QMK layer are separate directories you can read apart. `data/`, `layouts/`, and `users/` carry the definition and keymap side, while `lib/` and `modules/` hold vendored code. Licensing is not one file either: the metadata says GPL-2.0, and the root carries `license_GPLv2.md`, `license_GPLv3.md`, and `license_Modified_BSD.md` side by side, which tells you parts of the tree carry different terms. Default branch is master, and the root readme is mostly a pointer, sending readers to docs.qmk.fm for anything beyond the keyboard list.
The build shells out to the qmk CLI before it compiles anything
The top-level Makefile hard-codes the external CLI name and uses it to work out where user files live, before any compiler runs. It first tries the modern query and falls back to the legacy config key:
QMK_BIN := qmkexport override QMK_USERSPACE := $(shell \
$(QMK_BIN) env | sort | grep -q QMK_USERSPACE \
&& $(QMK_BIN) env QMK_USERSPACE \
|| $(QMK_BIN) config -ro user.overlay_dir | cut -d= -f2 | sed -e 's@ [(].*[)]$$@@g' | sed -e 's@^None$$@@g')The comment above those lines names the versions this handles, a direct query on qmk_cli 1.1.7 and up, with the `user.overlay_dir` path as the legacy method that only supported user overlays. The `sort` on the first call exists to buffer `qmk env` output and avoid BrokenPipeError, which the same comment says out loud. The consequence is that userspace detection depends on that CLI: if neither query returns a value, QMK_USERSPACE ends up empty.
No GitHub releases, so the version banner is a git tag lookup
The repository has no GitHub releases, so there is nothing to download and nothing to pin from a release page. The Makefile asks git for the most recent tag instead, and then goes quiet in three separate situations.
QMK_VERSION := $(shell git describe --abbrev=0 --tags 2>/dev/null)$(info QMK Firmware $(QMK_VERSION))A tree that is not a git work tree exports both `SKIP_GIT` and `NOT_REPO`, and defining `SKIP_VERSION` exports `SKIP_GIT` too. The `2>/dev/null` on the tag lookup is what keeps a tagless or gitless tree from spraying errors into your build log. The consequence for you is that an export which drops `.git` has no version to report and `$(info ...)` never fires, which is not fatal but leaves you with no version string to quote when a keyboard misbehaves and you need to state what was running. The tag lookup is also why release discipline lives in git history here rather than in a published artifact list.
.NOTPARALLEL, and the comment that says what -j still buys you
The top-level Makefile opts out of parallel execution and carries a plain comment about the reason.
# Never run this makefile in parallel, as it could screw things up
# It won't affect the submakes, so you still get the speedup from specifying -jx.NOTPARALLEL:The same comment concedes the submake exception, so the speedup you can actually claim has to come from the jobserver flags you pass yourself. What this cannot do is turn one board target into a parallel build just because you asked for it. Someone typing a high `-j` value expecting every core to work on a single keyboard will not get that at the top level,. The file also strips directory chatter for readability, and the comment above that line says why: to avoid Entering and Leaving directory messages, which means a build log is short enough to read but has no directory trail to reconstruct where a failure happened.
override SILENT := false makes quiet at the top level a no-op
Two spellings of the silence flag are accepted, with lowercase handled the same way as uppercase.
ifneq ($(VERBOSE),true)
.SILENT:
endifoverride SILENT := falseWhatever you pass, the value is handed down to submakes through `SUB_IS_SILENT` and then forced back off at the root. The in-file reason is spelled out: silent is always turned off at the top level, otherwise the [OK], [ERROR] and [WARN] messages will not be displayed correctly. So quiet mode is deliberately one-way. You can push the flag down and get terse output from the layers below while still getting the top-level status lines, which is the part you want when a compile fails. What it cannot do is suppress the final verdicts at the root, so anything scripting output parsing has to expect those three markers no matter which flags you passed, and a build that is quiet everywhere else still ends by announcing its result.
requirements.txt has eleven packages, two floors, one commented-out line
The Python side is pinned in a single root file, and its shape says more than the package names do. The first entry is deliberately disabled:
# platformdirs
argcomplete
colorama
dotty-dict
hid
hjson
jsonschema>=4
milc>=1.9.0
pygments
pyserial
pyusb
pillowOnly two entries carry a version floor, `jsonschema>=4` and `milc>=1.9.0`, so those are the two that constrain behavior rather than simply add a module. The rest is a second root file, `requirements-dev.txt`, for the developer-only set, plus `setup.cfg` and `nose2.cfg` for the surrounding tooling. Nine of the eleven carry no floor at all, which means a fresh environment resolves them to whatever is current, and a change in one of those can change what your build does without anything in this repository changing.
A fork inherits submodules, per-board directories, and a docs toolchain
`.gitmodules` sits at the root, so a clone is only the start, and the submodule content has to be present before the build has everything it expects. The directory layout is this project's real interface: `keyboards/` for hardware, `layouts/` for the keymap layer, `users/` for personal space, `data/` for shared definitions, `tests/` for the test tree, `util/` for tooling, and `docs/` for the documentation sources. The docs are not a wiki but a VitePress site published at docs.qmk.fm, and the root readme points at a contributing page section on previewing the documentation because those docs are also viewable offline. Changes travel the route that page names, a fork followed by a pull request. Root dotfiles matter for that work: `.clang-format` governs C formatting, `.clangd` sets editor language server behavior, `.editorconfig` handles the rest, and a `Doxyfile` covers generated documentation.
Six boards carry a named maintainer, the rest are community support
The supported list names six keyboard lines, and each one has a person attached to it. That mapping is the practical difference between them and everything else in the tree.
- Planck - Preonic - ErgoDox EZ - Clueboard - Cluepad - Atreus
QMK is developed and maintained by Jack Humbert of OLKB with contributions from the community and credit to Hasu, and the product firmwares are split the same way: OLKB to Jack Humbert, the Ergodox EZ to ZSA Technology Labs, the Clueboard to Zach White, and the Atreus to Phil Hagelberg. Below that list, the readme points to a longer directory of lots of other keyboards under community support. The limit is worth stating plainly, because it decides who answers you. If your board is not in the first list, this repository names nobody who owns it, so an issue against a community board has no maintainer here on the hook for it, and you should budget your own time for a fix rather than waiting on a maintainer response.
Editorial conclusion
QMK fits someone who owns a supported board and wants their layers, macros, and tapping behavior under their own control. It does not fit someone who wants a packaged installer or a downloadable release artifact, because the repository publishes no GitHub releases and the version banner comes from a git tag lookup that disappears the moment the tree is not a work tree. Before you commit, confirm your exact board lives under keyboards/, check whether it sits in the six named maintainer lines or only under community support, and confirm the qmk CLI is on your PATH, because the top-level Makefile calls it before compiling anything to locate your userspace. GPL-2.0 covers the firmware, and the root also carries GPLv3 and Modified BSD license texts for the parts that use them.
Frequently asked questions
What is QMK firmware?
Open-source keyboard firmware written in C for Atmel AVR and Arm USB families, grown out of the tmk_keyboard firmware, released under GPL-2.0, with its default branch named master. Its top-level Makefile drives the build and shells out to the qmk CLI to locate your user space before compiling anything.
What does QMK mean?
The repository title spells it out as Quantum Mechanical Keyboard Firmware, which is also the name of the project site at qmk.fm and the documentation host at docs.qmk.fm.
Should I use QMK or via?
The repository makes no comparison with via, so it cannot answer that. What it does record is its own base, the tmk_keyboard firmware, and the controller families it targets, Atmel AVR and ARM, along with the specific boards it names as supported.
where is qmk firmware folder
Board and keymap content lives in the `keyboards/`, `layouts/`, and `users/` directories at the repository root, with shared definitions in `data/`. On top of that, the top-level Makefile resolves a separate user space named QMK_USERSPACE before the build starts, falling back to a `user.overlay_dir` config value.
qmk firmware vscode
Editor setup is shipped as root-level files rather than as instructions. The top-level entries include `.vscode/`, `.clangd` for the C language server, `.editorconfig` for the rest of the tree, and `.clang-format` for C formatting. The root readme itself points readers to docs.qmk.fm for anything beyond the keyboard list.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/qmk-qmk-firmware)Star history chart for your README
[](https://hysenlabs.com/projects/qmk-qmk-firmware)Was this useful?