Expand description
A modern, easy-to-use, and feature-rich keyboard firmware written in Rust.
👉 Join our Discord server for discussions, support, and community collaboration!
§Features
- Broad microcontroller compatibility: Leveraging embassy, RMK supports a comprehensive range of microcontrollers, including stm32, nRF, rp2040(w), esp32, etc
- Dynamic keymap customization: RMK offers real-time keymap modifications through Vial, or its native Rynk protocol (experimental). You can even edit keymaps over BLE connections wirelessly
- Advanced keyboard functionality: RMK comes with lots of advanced keyboard features by default, including layer switching, media controls, system commands, mouse control, and more
- Wireless connectivity: BLE wireless support with automatic reconnection and multi-device capabilities for nRF52, nRF54, esp32, Pi Pico W and SF32LB52 microcontrollers, tested on nRF52840, nRF54L15, nRF54LM20, esp32c3, esp32c6, esp32h2, esp32s3, Pi Pico W
- Easy configuration: RMK simplifies keyboard development through a single
keyboard.tomlconfiguration file. For Rust enthusiasts, the firmware remains highly customizable using Rust code - Optimized performance: RMK achieves approximately 2ms latency in wired mode and 10ms in wireless mode. With the
async_matrixfeature enabled, power consumption is significantly reduced—a 2000mAh battery can power your keyboard for several months
§User Documentation | API Reference | FAQs | Changelog
§Real-World Implementations
§Getting Started
§Option 1: Start with a Template
Quickly bootstrap your project using rmkit and the official RMK project template.
cargo install rmkit flip-link
# If you encounter installation issues on Windows, try this alternative command:
# powershell -ExecutionPolicy ByPass -c "irm https://github.com/rmk-rs/rmkit/releases/latest/download/rmkit-installer.ps1 | iex"
rmkit initFor comprehensive guidance, refer to the User Guide.
§Option 2: Explore Built-in Examples
Browse the examples in the examples directory. Below are step-by-step instructions for rp2040 development. The process is similar for other microcontrollers when using a debug probe.
§rp2040 Setup
-
Install probe-rs
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/probe-rs/probe-rs/releases/latest/download/probe-rs-tools-installer.sh | sh -
Build the firmware
cd examples/use_rust/rp2040 cargo build --release -
Flash using a debug probe
With a debug probe connected to your rp2040 board, simply run:
cd examples/use_rust/rp2040 cargo run --release -
(Optional) Flash via USB
Without a debug probe, you can use
elf2uf2-rsto flash via USB:- Install the tool:
cargo install elf2uf2-rs - Modify
examples/use_rust/rp2040/.cargo/config.tomlto useelf2uf2:- runner = "probe-rs run --chip RP2040" + runner = "elf2uf2-rs -d" - Connect your rp2040 board while holding the BOOTSEL button until the USB drive appears
- Flash the firmware:Upon successful completion, you’ll see output similar to:
cd examples/use_rust/rp2040 cargo run --releaseFinished release [optimized + debuginfo] target(s) in 0.21s Running `elf2uf2-rs -d 'target\thumbv6m-none-eabi\release\rmk-rp2040'` Found pico uf2 disk G:\ Transfering program to pico 173.00 KB / 173.00 KB [=======================] 100.00 % 193.64 KB/s
- Install the tool:
§Development Roadmap
Current roadmap of RMK can be found here.
§Minimum Supported Rust Version (MSRV)
RMK is developed against the latest stable Rust release. While other versions may work, they are not fully tested.
§License
RMK is licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
§Feature flags
watchdog(enabled by default) — Enable hardware watchdog supporthost(enabled by default) — Enable host configurator supportvial(enabled by default) — Enable vial supportdfu_lock— Experimental. Enable DFU lock feature — physical key unlock for DFU firmware downloadhost_lock(enabled by default) — Enable physical key unlock and matrix state tracking — the shared base of the lock features (dfu_lockandrynkimply it; combine withvialfor the Vial lock).rynk— Experimental. Enable Rynk protocol support (RMK-native protocol, mutually exclusive with vial). The wire protocol and host API can change in any release;vialis the stable default. Includeshost_lockso the lock gate always has matrix-state tracking.dongle— Enable dongle support. Both sides of a dongle setup enable it: the keyboard gets a bond slot of its own for the dongle plus theSwitchToDonglekey, the dongle binary getsrmk::dongle. The dongle relays the keyboard’s host protocol: Rynk by default, or Vial when both binaries also enablevial.storage(enabled by default) — Enable the storage. The storage is optional to save memorydefmt(enabled by default) — Enable defmt supportusb_log— Enable logging via usblog— Use log, this feature cannot be enabled when defmt is enabledstd— Activate the embassy-time mock driver for deterministic, fast test timing. (Despite the historic name, this feature does NOT enable embassy-time/std — it swaps in the manually-advanced mock clock driven byrmk::test_support::test_block_on.)display— Enable display support (traits + processor)ssd1306— Enable SSD1306 OLED driveroled_async— Enable OLED drivers via oled_async (SH1106, SH1107, SH1108, SSD1309)lcd_async— Enable TFT drivers via lcd-async (GC9107, GC9A01, ILI9225, ILI9341, ILI9342C, ILI9486, ILI9488, RM67162, ST7735, ST7789, ST7796).async_matrix— Enable async matrix scanninguse_1m_phy— Use 1M PHY toward the host. The dongle link and the split link are unaffected: they always run at 2M.split— Enable split keyboard support.rp2040— Enable feature to use rp2040 specific features, like PIO and bootromadafruit_bl— Enable feature if you’re using Adafruit nRF52 bootloader and want bootloader jumping keyzsa_voyager_bl— Enable feature if you’re using the ZSA Voyager ignition DFU bootloaderdfu— Experimental. Enable DFU firmware update support (USB DFU interface). The flash layout, config, and API can change in any release.dfu_rp— Experimental. Enable RP2040-specific DFU with embassy-boot-rp (impliesdfuandrp2040)dfu_nrf— Experimental. Enable nRF DFU firmware update support (add a chip feature likenrf52840too)dfu_split— Experimental. Enable split firmware update support — forward firmware to peripherals over split link. Wired split only; see the guard inlib.rsfor BLE.steno— Enable Plover HID stenography support: adds the steno HID descriptor, the steno USB writer endpoint, and theAction::Stenovariant._no_usb— Internal feature that indicates no USB is used, this feature will be auto-activated for some chips_usb_high_speed— Internal marker for 480 Mbps USB chips; activates 512-byte bulk packets._no_saadc— Internal marker for chips without SAADC; compiles outNrfAdc.subrating— Enable BLE connection subrating for split Connections_no_subrating— Internal feature that indicates that subrating is not supported, this will be auto-activated for some chips
§BLE feature flags
⚠️ Due to the limitation of docs.rs, functions gated by BLE features won’t show in docs.rs. You have to head to examples folder of RMK repo for their usages.
nrf54lm20_ble— Enable feature if you want to use nRF54LM20 with BLE.nrf54l15_ble— Enable feature if you want to use nRF54L15 with BLE.nrf52840_ble— Enable feature if you want to use nRF52840 with BLE.nrf52833_ble— Enable feature if you want to use nRF52833 with BLE.nrf52820_ble— Enable feature if you want to use nRF52820 with BLE. The chip has no SAADC, soNrfAdcis unavailable.nrf52832_ble— Enable feature if you want to use nRF52832 with BLE.nrf52811_ble— Enable feature if you want to use nRF52811 with BLE.nrf52810_ble— Enable feature if you want to use nRF52810 with BLE.esp32c3_ble— Enable feature if you want to use ESP32C3 with BLE.esp32c6_ble— Enable feature if you want to use ESP32C6 with BLE.esp32h2_ble— Enable feature if you want to use ESP32H2 with BLE.esp32s3_ble— Enable feature if you want to use ESP32S3 with BLE.pico_w_ble— Enable feature if you want to use RP2040W with BLE.sf32lb52x_ble— Enable feature if you want to use SF32LB52x with BLE.passkey_entry— Enable passkey entry support for BLE pairing_ble— Enable feature if you want to use trouble BLE stack
Re-exports§
pub use keymap::KeymapData;pub use embassy_futures;pub use embassy_time;pub use futures;pub use heapless;pub use rmk_macro as macros;pub use rmk_types as types;
Modules§
- ad_
types - UUIDs for the ad types module.
- appearance
- The representation of the external appearance of the device.
- ble
- boot
- browse_
group_ identifiers - UUIDs for the browse group identifiers module.
- channel
- Exposed channels which can be used to share data across devices & processors
- characteristic
- UUIDs for the characteristic module.
- config
- core_
traits - debounce
- declarations
- UUIDs for the declarations module.
- descriptors
- UUIDs for the descriptors module.
- driver
- event
- Event system for RMK
- helper_
macro - hid
- host
- input_
device - Input device module for RMK
- keyboard
- keyboard_
macros - keymap
- layout_
macro - light
- matrix
- mesh_
profile - UUIDs for the mesh profile module.
- object_
types - UUIDs for the object types module.
- processor
- Runtime traits for event consumers in RMK.
- protocol_
identifiers - UUIDs for the protocol identifiers module.
- service
- UUIDs for the service module.
- service_
class - UUIDs for the service class module.
- split
- state
- storage
- units
- UUIDs for the units module.
- usb
- watchdog
Macros§
- a
- Create a KeyAction variant directly.
- df
- Create a default layer switch action.
- encoder
- Create a rotary encoder action.
- join_
all - Helper macro for joining all futures
- k
- Create a normal key action.
- kbctrl
- Create a keyboard control action.
- layer
- Create a layer in keymap.
- light
- Create a light control action.
- lm
- Create a layer activation with modifier action.
- lt
- Create a layer-tap action (tap/hold behavior).
- ltp
- Create a layer-tap action with custom timing profile.
- macros
- Create a macro trigger action.
- mo
- Create a momentary layer activation action.
- morse
- Create a Morse action (alias for tap dance).
- mt
- Create a modifier-tap action (tap/hold behavior).
- mtp
- Create a modifier-tap action with custom timing profile.
- osl
- Create a one-shot layer action.
- osm
- Create a one-shot modifier action.
- Create a persistent default layer switch action.
- run_all
- Run multiple tasks concurrently by calling each task’s
runmethod. - select_
biased_ with_ feature - Wrapper for select_biased! with feature-gated arms
- shifted
- Create a shifted key action.
- special
- Create a special key action.
- td
- Create a tap dance action (Morse action).
- tg
- Create a layer toggle action.
- th
- Create a dual-key tap-hold action.
- thp
- Create a dual-key tap-hold action with custom timing profile.
- to
- Create a “to layer” action (exclusive layer activation).
- tt
- Create a layer tap-toggle action.
- ttp
- Create a layer tap-toggle action with custom timing profile.
- user
- Create a user key action with given index.
- uuid
- Create a UUID object from a string or other convertible literal, similar to how UUIDs can be specified in a gatt_service derivation.
- with_
feature - wm
- Create a key action with modifier combination.
Structs§
- AdStructure
Iter - Iterator over advertisement structures.
- Addr
Kind - AddrKind
- Address
- A BLE address. Every BLE device is identified by a unique Bluetooth Device Address, which is a 48-bit identifier similar to a MAC address. BLE addresses are categorized into two main types: Public and Random.
- AdvChannel
Map - AdvChannelMap
- AdvHandle
- AdvHandle
- AdvSet
- AdvSet
- Advertisement
Parameters - Parameters for an advertisement.
- Advertisement
Set - Configuriation for a single advertisement set.
- Advertiser
- Handle to an active advertiser which can accept connections.
- AttError
Code - Attribute Error Code
- AttPermissions
- Attribute permissions
- Attribute
- Attribute metadata.
- Attribute
Iterator - Iterator over attributes.
- Attribute
Server - A GATT server capable of processing the GATT protocol using the provided table of attributes.
- Attribute
Table - A table of attributes.
- Attribute
Value - A value of an attribute.
- Auto
Mouse Layer Runner Runnablefor the auto mouse layer task.- BdAddr
- BdAddr
- Bluetooth
Uuid16 - A 16-bit Bluetooth UUID
- Bluetooth
Uuid32 - A 32-bit Bluetooth UUID
- Bluetooth
Uuid128 - A 128-bit Bluetooth UUID
- Bond
Information - Bond Information
- CCCD
- CCCD flag.
- Central
- A type implementing the BLE central role.
- Central
Config - Configuration for a central device GAP Service.
- Characteristic
- A characteristic in the attribute table.
- Characteristic
Builder - Builder for characteristics.
- Characteristic
Properties Handle - Attribute handle for a characteristic’s properties
- Characteristic
Props - Properties of a characteristic.
- Client
AttTable - A compact, fixed-size map of client-specific attribute values (e.g. CCCDs).
- Client
AttTable Builder - A builder for
ClientAttTable. - Client
AttTable View - A read-only view over a serialized
ClientAttTable. - Conn
Params - Current parameters for a connection.
- Connect
Config - Connection configuration.
- Connect
Rate Params - Connection rate parameters.
- Connection
- Handle to a BLE connection.
- Connection
Params Request - A connection parameters update request
- Control
Runner - The control part of the host runner.
- Descriptor
- Characteristic descriptor handle.
- External
Controller - An external Bluetooth controller with communication via
TransporttypeT. - Gatt
Client - A GATT client capable of using the GATT protocol.
- Gatt
Connection - Used to manage a GATT connection with a client.
- Gatt
Data - A GATT payload ready for processing.
- Host
Metrics - Host metrics
- Host
Resources - HostResources holds the resources used by the host.
- Identity
- Identity of a peer device
- Identity
Resolving Key - Identity Resolving Key.
- Invalid
Handle - Invalid handle value
- Invalid
Length Error - An error returned when a byte slice has an invalid length for a Bluetooth UUID.
- L2cap
Channel - Handle representing an L2CAP channel.
- L2cap
Channel Config - Configuration for an L2CAP channel.
- L2cap
Channel Listener - A listener for incoming L2CAP connection requests on a specific connection.
- L2cap
Channel Reader - Handle representing an L2CAP channel write endpoint.
- L2cap
Channel Ref - Handle to an L2CAP channel for checking it’s state.
- L2cap
Channel Writer - Handle representing an L2CAP channel write endpoint.
- L2cap
Pending Connection - A pending incoming L2CAP connection that can be inspected, then accepted or rejected.
- LeAdv
Reports Iter - An iterator for advertising reports.
- LeExt
AdvReports Iter - An iterator for extended advertising reports.
- Long
Term Key - LE Secure Connections Long Term Key.
- NotAllowed
Event - Other event returned while processing GATT requests (neither read, nor write).
- Notification
- A notification payload.
- Notification
Listener - Notification listener for GATT client.
- OobData
- OOB data for BLE pairing, exchanged via an out-of-band channel.
- Other
Event - Other event returned while processing GATT requests (neither read, nor write).
- Peripheral
- Type which implements the BLE peripheral role.
- Peripheral
Config - Configuration for a peripheral device GAP Service.
- PhyMask
- PhyMask
- Read
Event - A characteristic read event returned while processing GATT requests.
- Reply
- A reply to a gatt request.
- Requested
Conn Params - Requested parameters for a connection.
- Runner
- Runs the host with the given controller.
- RxRunner
- The receiver part of the host runner.
- Scan
Config - Scan/connect configuration.
- Scan
Session - Handle to an active advertiser which can accept connections.
- Scanner
- A scanner that wraps a central to provide additional functionality around BLE scanning.
- Sdu
- Service Data Unit
- Service
- A GATT service.
- Service
Builder - Builder for constructing GATT service definitions.
- Service
Handle - Handle for a GATT service.
- Stack
- Contains the host stack
- Stack
Builder - Builder for configuring the BLE stack before use.
- Subrating
Params - Connection subrating parameters
- TxRunner
- The transmit part of the host runner.
- Write
Event - A characteristic write event returned while processing GATT requests.
Enums§
- AdStructure
- Advertisement data structure.
- AdvFilter
Policy - AdvFilterPolicy
- Advertisement
- Advertisement payload depending on which advertisement kind requested.
- Advertisement
Data Error - Error encoding advertisement data.
- BleHost
Error - Errors returned by the host.
- Bluetooth
Uuid - A Bluetooth UUID of any valid length (16, 32, or 128 bits).
- CCCD
Flag - CCCD flag values.
- Characteristic
Prop - Characteristic properties
- Connection
Event - A connection event.
- Credit
Flow Policy - Control how credits are issued by the receiving end.
- Error
- Errors related to Host.
- GapConfig
- Configuration for the GAP Service.
- Gatt
Connection Event - A GATT connection event.
- Gatt
Event - An event returned while processing GATT requests.
- IoCapabilities
- Device I/O capabilities
- LeCredit
Conn Result Code - Result code for an LE Credit Based Connection Response.
- Pairing
Failed Reason - Pairing Failed Reason
- Permission
Level - Attribute permissions
- PhyKind
- PhyKind
- PhySet
- PHYs to scan on.
- Role
- LeConnRole
- Security
Level - Security level of a connection
- TxPower
- Transmit power levels.
- Uuid
- A 16-bit or 128-bit UUID.
Constants§
- AD_
FLAG_ LE_ LIMITED_ DISCOVERABLE - Le advertisement.
- BR_
EDR_ NOT_ SUPPORTED - BR/EDR not supported.
- GAP_
SERVICE_ ATTRIBUTE_ COUNT - The number of attributes added by the GAP and GATT services (with security)
- LE_
GENERAL_ DISCOVERABLE - Discoverable flag.
- MAX_
SMALL_ DATA_ SIZE - The maximum size in bytes of an attribute using inline small data storage.
- SIMUL_
LE_ BR_ CONTROLLER - Simultaneous LE and BR/EDR to same device capable (controller).
- SIMUL_
LE_ BR_ HOST - Simultaneous LE and BR/EDR to same device capable (Host).
Traits§
- AsGatt
- Trait to allow conversion of a type to gatt bytes
- Attribute
Handle - A type which holds a handle to an attribute in the attribute table
- Controller
- Trait that defines the controller implementation required by the host.
- Dynamic
Attribute Server - Type erased attribute server
- Event
Handler - Event handler.
- Fixed
Gatt Value - Trait to allow conversion of a fixed size type to and from a byte slice
- From
Gatt - Trait to allow conversion of gatt bytes into a type
- Packet
- A Packet is a byte buffer for packet data.
Similar to a
Vec<u8>it has a length and a capacity. - Packet
Pool - A Packet Pool that can allocate packets of the desired size.
Functions§
Type Aliases§
- Default
Packet Pool - Global default packet pool.
- Heapless
String - A fixed capacity
String.
Attribute Macros§
- gatt_
server - Gatt Service attribute macro.
- gatt_
service - Gatt Service attribute macro.





