If you have ever attempted to implement Home Row Mods, create navigation layers, or customise tap-hold behaviours on a standard laptop keyboard without buying a $300 QMK/ZMK programmable split ergonomic keyboard, you know the struggle.
Standard OS-level tools like xmodmap, autohotkey, or basic macOS modifiers often fall short when handling complex layered interactions, sub-millisecond tap-hold detection, or display server transitions (like moving between X11 and Wayland).
Enter software-based daemon remappers. Three of the most prominent tools in this ecosystem are:
- rvaiya/keyd — The C-based Linux kernel daemon benchmark.
- jtroo/kanata — The cross-platform Rust powerhouse.
- argenkiwi/keydo — The Rust-based "keyd, oxidised" alternative bridging ergonomic syntax and multi-platform goals.
In this article, we’ll break down how they compare across architecture, configuration syntax, cross-platform support, and unique capabilities so you can choose the right tool for your setup.
High-Level Overview
Here is a bird's-eye comparison of the three projects:
| Feature / Aspect |
keyd (rvaiya/keyd) |
kanata (jtroo/kanata) |
keydo (argenkiwi/keydo) |
|---|---|---|---|
| Language | C | Rust | Rust |
| Primary Platform | Linux (Kernel level: evdev/uinput) | Cross-Platform (Linux, macOS, Windows) | Multi-Platform Vision (Linux, macOS) |
| Configuration Style | INI / Declarative (/etc/keyd/) |
Lisp / S-expressions (.kbd) |
INI / Keyd-inspired Syntax |
| Philosophy | Minimalist, UNIX-way, sub-1ms speed | Feature-maximalist, highly customizable | Clean INI simplicity + Rust safety/portability |
| Live Reloading | Yes (keyd reload) |
Yes (automatic file watch) | Yes |
| Application Remapping | Native IPC / app-specific bindings | External integration via TCP / scripts | In development |
| Complexity Curve | Very low (easy to learn in 5 mins) | Moderate to high (steep initial syntax) | Low (intuitive keyd-style syntax) |
1. keyd (rvaiya/keyd) — The Linux Benchmark
What is it?
keyd is a system-wide key remapping daemon for Linux written in C. It operates at the kernel level via evdev and uinput. Because it hooks into Linux's input subsystem below the display server layer, your custom keybindings work identically across X11, Wayland compositors (Sway, Hyprland, GNOME), and even pure virtual consoles (TTYs).
Key Strengths
- Unbeatable Performance & Low Overhead: Hand-tuned C loop executing input transformations in under 1 millisecond with near-zero memory footprint.
- Intuitive INI Configuration: The syntax is dead simple. Creating a navigation layer or overloading Caps Lock takes seconds.
-
First-Class Modifiers & Composite Layers: Supports syntax like
[control+alt]or modifier-blended layers out of the box without complex boilerplate. - Application-Aware Remapping: Ships with an IPC client mechanism allowing context-sensitive layers dependent on the focused window (e.g., terminal vs. browser).
Drawbacks
-
Linux Only: Deeply tied to Linux kernel primitives (
/dev/input/evdev,/dev/uinput). It cannot run natively on macOS or Windows.
2. kanata (jtroo/kanata) — The Cross-Platform Powerhouse
What is it?
kanata is a cross-platform keyboard remapper written in Rust. Born out of the desire to bring advanced QMK/Kinesis-style firmware logic to software remappers, Kanata runs seamlessly on Linux, macOS, and Windows.
Key Strengths
- True Cross-Platform Consistency: Use the exact same core remapping logic and Home Row Mod timings whether you are on your Linux workstation, MacBook, or Windows gaming rig.
-
Granular Tap-Hold Customization: Offers fine-grained primitives like
tap-hold-press,tap-hold-release, chord groups, leader key sequences, and Unicode output macros. - Extensibility & Interprocess Communication: Includes an optional TCP server so external scripts or status bars (Polybar, Waybar, SketchyBar) can listen to active layer states or trigger layer shifts dynamically.
- Active Community Ecosystem: Widely adopted in the ergonomic keyboard community (e.g., used by projects like Kenkyo).
Drawbacks
-
Lisp Syntax Learning Curve: Config files use S-expressions (
defsrc,deflayer,defalias). For users unfamiliar with Lisp or Scheme formatting, reading and debugging nested parens can be daunting initially.
3. keydo (argenkiwi/keydo) — The "Keyd, Oxidised" Alternative
What is it?
keydo, created by Leandro (argenkiwi) (author of the Kenkyo ergonomic ANSI layout), is an open-source project described as "Keyd, oxidised". It was started to solve a specific pain point: lovers of keyd's clean, intuitive INI configuration file format wanted those same ergonomics on platforms beyond Linux without having to convert everything to Kanata's S-expression syntax.
Key Strengths
-
The Best of Both Worlds: Combines the human-readable, minimal INI configuration design of
keydwith the memory safety, concurrency, and cross-platform potential of Rust. -
Familiar Mental Model for keyd Users: If you already have a
keydsetup or prefer readablekey = overload(control, esc)directives over nested Lisp macros,keydooffers an approachable path. - Designed with Ergonomic Workflows in Mind: Born from hands-on experimentation with home row modifiers, custom chords, and thumb-shift patterns on standard ANSI boards.
Drawbacks
-
Newer Project: Compared to the battle-tested
keyd(C) andkanata(Rust),keydois younger and under active development, so some niche features or edge-case platform drivers may still be maturing.
Configuration Comparison: A Practical Example
To see how these tools differ in practice, let's look at how you configure a classic ergonomic pattern:
Goal: Turn
Caps LockintoEscapewhen tapped, andControlwhen held. When holdingCaps Lock, pressj,k,h,lfor arrow navigation.
keyd (/etc/keyd/default.conf)
ini
[ids]
*
[main]
capslock = overload(nav, esc)
[nav:C]
h = left
j = down
k = up
l = right
Top comments (0)