kmap is a low-level Linux keyboard remapper written in Go.
It reads events from one or more real keyboard devices, applies mapping rules from YAML, and emits remapped key events through a virtual keyboard on /dev/uinput.
- Build the binary:
make build- Install the active config at
/etc/kmap/kmap.yaml:
sudo install -d /etc/kmap
sudo install -m 644 ./kmap.yaml /etc/kmap/kmap.yaml-
Edit
/etc/kmap/kmap.yamlfor your machine:- set
devices:if you want anything other than the built-in default device path - adjust
shortcut_layout,tap_layout_switches, andmappings
- set
-
Validate the config:
./bin/kmap validate-config- Start the daemon:
./bin/kmap startkmap start automatically generates ~/.XCompose before the daemon begins remapping, so to_symbol mappings stay aligned with the running config.
- Linux with access to
/dev/input/...keyboard devices - access to
/dev/uinput - if you use
shortcut_layoutortap_layout_switches, KDE withqdbus6
If you run kmap as an unprivileged user, that user must have permission to read the input devices and open /dev/uinput.
The default config path is:
/etc/kmap/kmap.yaml
You can override it with --config <path> on any command.
The repository root kmap.yaml is an example config you can copy and adapt.
devices: accepts one or more /dev/input/... paths. Good stable choices are usually under /dev/input/by-id/ or /dev/input/by-path/.
If devices: is omitted, kmap falls back to the built-in default path:
/dev/input/by-path/platform-i8042-serio-0-event-kbd
Each mapping supports exactly one action:
passthrough: truepause: trueto_symbol: …to_keys: [...]to_chord: Ctrl-Shift-X
Bindings support exact modifier combinations, including combinations such as Ctrl-Alt-Shift-Meta-K.
You can define a hotkey that pauses remapping and releases input grabs. While paused, physical keyboards pass through directly. Press the same hotkey again to resume.
Example:
mappings:
Caps-Backspace:
pause: trueThis is intended as a safety mechanism if a bad mapping leaves the daemon in an unusable state.
kmap start [--config /etc/kmap/kmap.yaml] [--device /dev/input/...]
kmap generate-xcompose --output ~/.XCompose [--config /etc/kmap/kmap.yaml]
kmap validate-config [--config /etc/kmap/kmap.yaml]Run help for details:
kmap <command> -hThe repository includes a generic user service in services/kmap.service.
Install it with:
make installThis installs:
~/.local/bin/kmap~/.config/systemd/user/kmap.service
and enables the service with systemctl --user.
Useful targets:
make restart
make uninstallWhen you run kmap start, the app does this:
- Load
/etc/kmap/kmap.yamlby default. - Generate
~/.XComposefrom all configuredto_symbolmappings. - Resolve input devices from
--device,devices:, or the built-in default device path. - Start one independent input pipeline per device.
- Watch unavailable devices and capture them when they appear.
Each pipeline uses:
pkg/daemon/input: read Linux input events and manage EVIOCGRABpkg/daemon/mapper: apply remapping, compose emission, and pause toggle detectionpkg/daemon/output: send remapped events through a virtual keyboardpkg/daemon/shortcut: optional KDE shortcut layout switching
If shortcut_layout is configured, kmap validates that the target layout exists in KDE and temporarily switches to that layout while shortcut modifiers are held. This keeps shortcuts stable even when your typing layout is different.
tap_layout_switches can also assign tap-only actions to LAlt, RAlt, and Caps.
make build
make test
make lint