# keyd: a kernel-level key remapping daemon for Linux

> keyd remaps keys through evdev and uinput so the same config works in X11, Wayland and a virtual terminal. Here is how the daemon, its config format and the application mapper fit together, and where the approach stops.

**rvaiya/keyd** — A key remapping daemon for linux.

- Repository: https://github.com/rvaiya/keyd
- Stars: 6,004 · Forks: 284
- Language: C
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/rvaiya-keyd

## The problem keyd addresses, and who feels it

The README opens with a blunt claim: Linux lacks a good key remapping solution, and reaching a satisfactory result usually means combining tools such as xcape and xmodmap, with the outcome tied to a specific environment like X11. keyd's answer is a single system-wide daemon that remaps keys using kernel-level input primitives, evdev for reading and uinput for writing. Because the remapping happens below the display server, the same keymap applies in X11, in a Wayland compositor and in a virtual terminal.

The intended audience is narrower than "anyone who wants to change a key". The README lists people who want to experiment with custom layers and oneshot modifiers, people running several keyboards with different layouts on one machine, people who want to remap C-1 without breaking modifier semantics, and people who want to switch to a VT to debug something without losing their keymap. If that list describes your setup, the design choices below will read as sensible rather than exotic.

## How the daemon, the config and the IPC socket fit together

keyd is written in C and built as a single binary from src/*.c plus a virtual keyboard backend chosen at build time. The Makefile defaults VKBD to uinput, and an alternative usb-gadget backend exists for single board computers. The daemon reads input events from evdev devices, applies the mapping described in its configuration, and emits the result through uinput, which is why the remapping is invisible to the display server.

Configuration lives under /etc/keyd, with /etc/keyd/default.conf as the starting point. A file begins with an [ids] section listing the devices it applies to, followed by one or more mapping sections such as [main]. Key names come from keyd monitor. The man page is the reference for the format, and the README notes that the format changed across v2 releases, so configs written for v1 should be re-read against the man page rather than copied forward.

The modularity claim rests on an IPC mechanism documented in the man page. The daemon also ships keyd-application-mapper, a client that talks to keyd and applies different mappings depending on the focused application. The README describes this as experimental and says support currently exists for X, sway and gnome under Wayland.

## Installing keyd from source or from a distribution package

The README gives source installation as a three-step sequence. The build needs a C compiler and Linux kernel headers, which are already present on most systems. After cloning, make builds the binary and sudo make install places it, then systemd starts the service.

```bash
git clone https://github.com/rvaiya/keyd
cd keyd
make && sudo make install
sudo systemctl enable --now keyd
```

The README warns that master is the development branch and that things may occasionally break between releases, while tagged releases should be considered stable. If you would rather not track master, packages exist for several distributions. Debian 13 ("trixie") and later and Ubuntu 25.04 ("plucky") and later ship keyd, both installed with apt.

```bash
sudo apt install keyd
```

Fedora users are pointed at a COPR repository, openSUSE at a package installed with sudo zypper in keyd, Alpine, Arch, Gentoo and Void at their respective community packages. The README states plainly that these are maintained by community members and that no personal responsibility is taken for them.

## A first config: capslock as control on hold, escape on tap

The quickstart puts a minimal config in /etc/keyd/default.conf. The [ids] section with a wildcard matches every keyboard the daemon sees, and the [main] section holds the mappings. The two lines below are the README's own example: capslock becomes escape when tapped and control when held, and escape becomes capslock.

```ini
[ids]

*

[main]

# Maps capslock to escape when pressed and control when held.
capslock = overload(control, esc)

# Remaps the escape key to capslock
esc = capslock
```

After editing, sudo keyd reload applies the config set without restarting the service.

```bash
sudo keyd reload
```

Config errors land in the log and are read the usual way through the service manager, for example sudo journalctl -eu keyd. The README is explicit that a bad config can render a machine unusable, and offers backspace+escape+enter as a key sequence that causes keyd to terminate. That escape hatch is worth testing deliberately rather than discovering under pressure.

## The wildcard id and the mouse that types

The wildcard in [ids] is convenient and also the source of the most surprising failure in the README. Some mice, the Logitech MX Master is the named example, can emit keys and are therefore matched by the wildcard. The result is that a device you think of as a pointer silently receives your keyboard mapping. The README's advice is to blacklist such devices explicitly.

This is a design consequence rather than a bug: matching on device ids is what makes per-keyboard configuration possible, and a broad match is the price of a short config. If you run several keyboards with genuinely different layouts, you will end up enumerating ids anyway, at which point the wildcard stops being useful. keyd monitor is the tool for finding them, and the README notes a subtlety: while keyd is running, monitor shows keyd's output, so the original input events are only visible after stopping the daemon.

## Application-specific remapping and its dependencies

The application mapper is the part of keyd that reaches beyond a single global keymap. The README marks it experimental and requires the user to join the keyd group, then populate ~/.config/keyd/app.conf with per-application sections. The example maps alt+] and alt+[ to macros in alacritty and to tab navigation in chromium.

```ini
[alacritty]

alt.] = macro(C-g n)
alt.[ = macro(C-g p)

[chromium]

alt.[ = C-S-tab
alt.] = macro(C-tab)
```

Running keyd-application-mapper starts the client. The README suggests putting keyd-application-mapper -d in display server initialization logic such as ~/.xinitrc, unless you are running Gnome. Note the optional dependencies this pulls in: python for application-specific remapping, python-xlib only for X support, and dbus-python only for KDE support. A machine that only needs a static keymap does not need any of them.

## What keyd is not, and when another tool fits better

The README draws one boundary itself: keyd is not a tool for programming individual key up and down events. If your requirement is to intercept a specific press and release and emit something custom for each, you are outside the intended scope, and a userspace input hook such as the Python evdev bindings or an interception framework is the more direct route. Those tools run inside a session and inherit its lifetime and its display server assumptions, which is exactly the trade keyd avoids, but they give you per-event control that keyd's mapping model does not.

There is a second boundary the README implies without stating. keyd is a root-owned daemon sitting in the input path. Every keystroke passes through it. That is what buys system-wide consistency and VT support, and it is also why a malformed config can lock you out of your own machine. A tool that remaps only within a compositor cannot do that, and for some users that containment is worth more than the consistency.

## Maintenance, licensing and upgrade cost

keyd is MIT licensed, which places few obligations on how you use or redistribute it. The README's packaging section is worth reading with that in mind: distribution packages are contributed by community members, and the project states that no personal responsibility is taken for them. If you install from a package, the version you get and how promptly it tracks upstream is a distribution question, not an upstream one.

The repository's last push was on 2026-06-01, and the most recent release is v2.6.0 from 2025-12-19. The Makefile pins VERSION=2.6.0, so a source build identifies itself against that tag. Upgrades carry a specific cost that the README calls out: the config format has gone through several iterations since the first release, and users migrating from v1 are told to reread the man page. Anyone holding a config written against an older v2 release should expect to check it against the current man page rather than assume it still parses.

## Conclusion

Adopt keyd if you want one keymap that survives display server changes, works in a VT, and supports layers and tap/hold overloads without reflashing firmware. Skip it if you need per-event key up/down programming or you are unwilling to keep a root-owned daemon in the input path. Before trusting it, verify your keyboard's id with keyd monitor and confirm the backspace+escape+enter escape sequence actually terminates the daemon on your machine.

## FAQ

### What is keyd?

keyd is a key remapping daemon for Linux written in C. It remaps keys using kernel-level input primitives, evdev and uinput, so the mapping applies system-wide rather than inside one display server.

### How do I use keyd?

Install and start the service, place your mappings in /etc/keyd/default.conf, then run sudo keyd reload. The README's quickstart uses capslock = overload(control, esc) as the first mapping, and keyd monitor to find key names.

### Is there a good keymapper for Linux?

The README argues Linux lacks a good key remapping solution, since satisfactory results usually require combining tools like xcape and xmodmap and end up tied to X11. keyd is the project's answer: one system-wide daemon that also works in a VT.

### Can I reassign keyboard keys with keyd?

Yes. Mappings are written as key = action pairs in a section such as [main], as in the README's esc = capslock. Layers, key overloading and hybrid modifiers are listed among the features.

## Sources

- [Issues](https://github.com/rvaiya/keyd/issues)
- [License: MIT](https://github.com/rvaiya/keyd/blob/master/LICENSE)
- [README](https://github.com/rvaiya/keyd/blob/master/README.md)
- [Releases](https://github.com/rvaiya/keyd/releases)
- [rvaiya/keyd on GitHub](https://github.com/rvaiya/keyd)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/rvaiya-keyd
