DEV Community

Leandro
Leandro

Posted on

Keyboard Remapping on Steroids: keyd vs. kanata vs. keydo

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:

  1. rvaiya/keyd — The C-based Linux kernel daemon benchmark.
  2. jtroo/kanata — The cross-platform Rust powerhouse.
  3. 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 keyd with the memory safety, concurrency, and cross-platform potential of Rust.
  • Familiar Mental Model for keyd Users: If you already have a keyd setup or prefer readable key = overload(control, esc) directives over nested Lisp macros, keydo offers 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) and kanata (Rust), keydo is 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 Lock into Escape when tapped, and Control when held. When holding Caps Lock, press j, k, h, l for arrow navigation.

keyd (/etc/keyd/default.conf)


ini
[ids]
*

[main]
capslock = overload(nav, esc)

[nav:C]
h = left
j = down
k = up
l = right
Enter fullscreen mode Exit fullscreen mode

Top comments (0)