Open-source project
rmk-rs/rmk avatar
rmk-rs/rmk

RMK keyboard firmware: configuration, hardware support, and setup

A modern, easy-to-use, and feature-rich keyboard firmware written in Rust.

1,787 stars249 forksRustApache-2.0

At a glance

What is it?
RMK is a Rust keyboard firmware with wired and BLE support, dynamic keymaps, and configuration through keyboard.toml. It suits embedded developers who want Rust code alongside a higher-level board definition.
Who is it for?
Keyboard developers who want a Rust firmware core, dynamic keymaps, and support across common microcontroller families should evaluate RMK first. Projects that need guaranteed test coverage on older Rust versions or need every wireless feature documented as stable should avoid assuming parity.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

RMK's target hardware and keyboard workflow

RMK addresses embedded developers building custom keyboards rather than users installing firmware on a fixed commercial board. Its purpose is to provide a shared Rust firmware foundation for keyboard matrices, input handling, layers, communication, and board-specific hardware. The project describes compatibility with STM32, nRF, RP2040 and RP2040 wireless variants, and ESP32 families. Wireless support is documented for nRF52, nRF54, ESP32, Pi Pico W, and SF32LB52 devices. The README names specific boards on which wireless support was tested, including nRF52840, nRF54L15, nRF54LM20, several ESP32 variants, and Pi Pico W.

That range makes RMK relevant to hobbyists designing a PCB, firmware engineers porting a keyboard to a supported embedded target, and developers who want to change layouts without rebuilding all firmware logic. Basic keyboard behavior includes layer switching, media controls, system commands, and mouse control. Connectivity options include wired operation and BLE. The documented wireless behavior includes automatic reconnection and support for multiple devices.

RMK also targets users who dislike a configuration-only firmware workflow. Most projects can be centered on a single `keyboard.toml` file, while the firmware remains customizable through Rust code. That combination is a meaningful design choice: declarative configuration can keep board data separate from application logic, while Rust remains available for behavior that does not fit a simple matrix or keymap definition.

Configuration parsing, generated definitions, and runtime features

Based on the repository layout, RMK separates its runtime package into several Rust crates and associated tooling. The top level includes `rmk/`, `rmk-config/`, `rmk-macro/`, `rmk-types/`, and `rynk/`, alongside examples and documentation. The README explicitly identifies `keyboard.toml` as the primary board configuration mechanism. This arrangement suggests a flow in which a keyboard project declares its hardware and mapping data, RMK processes that configuration, and the firmware supplies runtime keyboard services. The repository layout supports that interpretation, although the README does not describe the internal parser step by step.

At runtime, the documented feature set covers both ordinary input and communication behavior. Matrix input feeds a firmware that supports layers and keyboard actions. Users can modify layouts through Vial, the native Rynk protocol, or BLE connections where wireless hardware support applies. Rynk is explicitly marked experimental in the README, so it should not be treated as interchangeable with the established Vial route without checking the relevant user guide.

The `async_matrix` feature has a separate purpose. According to the README, enabling it significantly reduces power consumption. RMK is built on Embassy, which is the stated basis for its broad microcontroller support. That dependency matters when evaluating a port because it forms part of the embedded execution environment rather than acting as an optional convenience library. The repository also separates types, configuration processing, and macros, which gives board projects defined integration points instead of requiring all definitions to live inside one firmware source file.

Creating and flashing an RMK rp2040 project

The documented quickest start uses `rmkit` and the official project template. On systems where that installation path has problems, the README gives a Windows PowerShell alternative. The tools install first, then `rmkit init` creates the initial project.

bash
cargo install rmkit flip-link
rmkit init

For Windows installation problems, the documented alternative is:

bash
powershell -ExecutionPolicy ByPass -c "irm https://github.com/rmk-rs/rmkit/releases/latest/download/rmkit-installer.ps1 | iex"

A more explicit first use is available through the RP2040 example. The README first directs developers to install `probe-rs`, then changes into the example directory and builds the release firmware.

bash
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/probe-rs/probe-rs/releases/latest/download/probe-rs-tools-installer.sh | sh
cd examples/use_rust/rp2040
cargo build --release

With a debug probe connected, the same example is launched with `cargo run --release`.

bash
cd examples/use_rust/rp2040
cargo run --release

For boards without a debug probe, the documented USB path uses `elf2uf2-rs`. Install the tool and change the runner in `examples/use_rust/rp2040/.cargo/config.toml`.

bash
cargo install elf2uf2-rs
diff
- runner = "probe-rs run --chip RP2040"
+ runner = "elf2uf2-rs -d"

Then hold BOOTSEL until the RP2040 appears as a USB drive and run the release command. The README shows a successful transfer ending at 100.00 percent, but the exact size, path, drive letter, and transfer speed belong to its example environment and should not be treated as fixed output.

Vial, Rynk, and BLE keymap editing choices

RMK offers more than one route for changing a keymap. Vial provides real-time customization and is documented as a supported keymap-editing option alongside RMK. This route is useful when a keyboard owner needs to remap keys without treating each layout change as a firmware modification. It also gives RMK an integration point with an existing configuration ecosystem rather than requiring every keymap change to pass through RMK's native protocol.

Rynk is RMK's own protocol, but the README labels it experimental. That label defines a clear adoption boundary. Developers can investigate it for native or wireless configuration, but they should verify its current command coverage, host compatibility, and persistence behavior in the Rynk documentation before selecting it as the only editing route for a product.

BLE editing is documented as possible for keyboards with supported wireless hardware. BLE support also includes automatic reconnection and multi-device capabilities according to the README. Those are separate concerns from runtime connectivity: the first concerns changing mappings over a wireless link, while the second concerns maintaining keyboard operation after connection changes.

The documented latency figures are approximately 2 ms in wired mode and 10 ms in wireless mode. These are project claims rather than results from an independent evaluation. They are useful as stated expectations, but keyboard designers should still account for their own matrix scanning, radio environment, host behavior, and feature configuration.

RMK's hardware boundaries and maintenance costs

RMK's breadth is useful only when a target falls within its supported hardware and feature combinations. Wireless support is not presented as universal across every listed family. The README narrows the tested BLE devices, and the presence of options such as `async_matrix` means battery behavior depends on configuration rather than one fixed keyboard design. A board using another ESP32, nRF, or RP2040 variant requires checking the relevant example and hardware documentation.

The Rynk protocol is another explicit boundary because the README calls it experimental. RMK also says it is developed against the latest stable Rust release. Other compiler versions may work, but they are not fully tested. That policy reduces ambiguity about the project's intended development baseline, although it can increase upgrade work for teams pinned to an older Rust toolchain. A new release may therefore involve checking the Rust version, target support, changed APIs, and the changelog rather than only replacing a binary.

The repository is not archived, and the last push was on 2026-10-16. Release history includes `rmk-v0.9.0` on 2026-08-29, after `rmk-v0.8.2` and `rmk-v0.8.1`. The repository links to `rmk/CHANGELOG.md`, which is the relevant source for change-specific upgrade work.

RMK is licensed under either Apache License, Version 2.0 or MIT license, at the user's option. That is a licensing choice rather than legal advice. Teams still need to review the repository license files and consider the licenses of dependencies when preparing firmware for distribution.

Choosing RMK instead of a handwritten firmware approach

A handwritten Rust keyboard firmware can keep matrix decoding, HID reports, transport code, and application behavior in one codebase. RMK takes a different approach by supplying a firmware package, configuration tooling, generated or processed definitions, and reusable keyboard features. Its advantage is less duplicated work for a new board. Its cost is accepting RMK's configuration model, supported hardware assumptions, and release compatibility constraints.

A configuration-led project is a sensible fit when the board mainly needs rows and columns, layers, actions, and a supported transport. The `keyboard.toml` workflow gives those projects a concise place to describe the keyboard, while Vial or Rynk can separate later mapping changes from firmware compilation.

Rust customization is the better route when behavior extends beyond the documented configuration model. The README states that the firmware remains customizable using Rust code. That flexibility matters for unusual scanning, custom actions, board-specific startup behavior, or transport integration, but the README does not document every public extension point. Such a project should consult the API reference and the `examples/use_rust` examples before committing.

RMK is the wrong tool when a project requires behavior outside its supported MCU families, depends on Rynk as a production-stable protocol, or assumes every listed wireless chip has identical feature parity. It is also a poor fit when the team cannot accept the latest stable Rust as its tested baseline. A small board with fully custom firmware requirements may gain little from the abstraction, while a multi-board keyboard project has more to reuse from it.

Editorial conclusion

Keyboard developers who want a Rust firmware core, dynamic keymaps, and support across common microcontroller families should evaluate RMK first. Projects that need guaranteed test coverage on older Rust versions or need every wireless feature documented as stable should avoid assuming parity. The first checks should be `keyboard.toml` against the physical matrix, the selected microcontroller example, and whether the required BLE or Rynk behavior is appropriate for the product. For an initial adoption decision, the relevant boundary is RMK's current configuration and its experimental wireless keymap protocol.

Frequently asked questions

What is RMK used for?

RMK is Rust firmware for custom keyboards. It supports matrix-based keyboard behavior, layers, actions, wired connectivity, and BLE on supported microcontroller families.

How do I start an RMK keyboard project?

Install `rmkit` and `flip-link`, then run `rmkit init` to create a project from the official template. The README also provides RP2040 examples under `examples/use_rust/rp2040`.

Does RMK support wireless keyboards?

Yes, but support is device-specific. The README lists BLE support for selected nRF52, nRF54, ESP32, Pi Pico W, and SF32LB52 devices, along with the boards on which it says wireless support was tested.

Can an RMK keymap be changed without rebuilding the firmware?

RMK supports real-time keymap modification through Vial. It also offers Rynk and wireless keymap editing on applicable connections, but the README labels Rynk experimental.

Which license can I use with RMK?

The README says RMK is available under either Apache License, Version 2.0 or the MIT license, at your option. Dependency licenses and distribution requirements still need separate review.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. rmk-rs/rmk on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/rmk-rs-rmk.svg)](https://hysenlabs.com/projects/rmk-rs-rmk)

Was this useful?