Open-source project
jtroo/kanata avatar
jtroo/kanata

jtroo/kanata: a cross-platform keyboard remapper with layers and tap-hold

Improve keyboard comfort and usability with advanced customization

7,945 stars293 forksRustLGPL-3.0

At a glance

What is it?
Kanata is a Rust keyboard remapper for Linux, macOS and Windows that lets any key switch to another layer of functionality. It is a good fit if you want tap-hold and macros without firmware, and a poor fit if you want a background service that starts itself.
Who is it for?
Adopt kanata if you want per-key layers, tap-hold and macros configured in a text file, and you accept a foreground process that needs elevated permissions to open the input devices. Do not adopt it if you want a service that starts at boot on its own, or if you need an official macOS driver shipped by this project; the README points at the Karabiner driver in the releases page instead.
Can I use it commercially?
Yes, with conditions. LGPL-3.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem kanata solves, and who ends up using it

Most people never think about the keyboard as a programmable device. The README makes the case with a comparison: if uppercase letters had their own physical keys instead of sharing keys with lowercase through Shift, nobody would accept the result. Shift works because it switches the keyboard to another layer of functionality. Kanata generalizes that idea so any key can switch layers, and the user decides what each layer does.

The target user is someone whose hands hurt, or whose workflow keeps hitting the same awkward chord. A programmer who wants a thumb key for Ctrl and Escape is the obvious case. So is anyone with a small keyboard who needs symbols that are not printed on it. The README lists the scope plainly: multiple layers of key functionality, and advanced behaviour such as tap-hold, macros and unicode output. Configuration lives in a human-readable file, and the repository ships samples from a minimal one up to kanata.kbd, which the README describes as an example of all features with documentation.

How the remapping pipeline is put together

The workspace layout shows the split. The root package builds the kanata binary and also exposes a library named kanata_state_machine. The keyberon directory holds a fork of the keyberon keyboard firmware library, and the parser directory holds kanata-parser. Both are versioned as path dependencies with the version 0.1121.0, matching the 1.12.1-prerelease-1 package version in Cargo.toml.

That means the configuration language is parsed by a separate crate, and the resulting actions are executed by the state machine. Keyberon is where the layer and key-event model comes from, which is why kanata can offer firmware-style behaviour on a desktop. The tcp_protocol crate defines the wire format for the optional TCP server, and example_tcp_client is a small program that talks to it, so other software can react to layer changes or trigger them. The interception directory is excluded from the workspace and carries its own MIT or Apache-2.0 licence, separate from the LGPL-3.0-only terms that cover contributions elsewhere.

Installing kanata and running a first config

The README offers pre-built binaries on the releases page, and also documents building from source. The project uses the latest Rust stable toolchain, so the first step is updating it. Then cargo install puts the binary on your path.

bash
rustup update stable
cargo install kanata

On Linux and macOS the README warns that this may not work without sudo, because kanata opens /dev/ files. The invocation is the same on every platform: pass the path to your configuration file with --cfg.

bash
kanata --cfg <your_configuration_file>

If you prefer to build in place, the README gives the clone and build sequence. The comment in the snippet notes that --release is optional and not really perf sensitive, which is a fair signal about where the cost sits: parsing and event dispatch, not raw throughput.

bash
git clone https://github.com/jtroo/kanata && cd kanata
cargo build
sudo target/debug/kanata --cfg <your_configuration_file>

On Windows the build is the same minus sudo, and the binary lands at target\debug\kanata. On macOS there is an extra prerequisite: install the Karabiner driver by following the macOS documentation on the releases page, then run with sudo to gain permission to intercept the keyboard. For a first configuration, start from cfg_samples/simple.kbd, which the README describes as basic and hopefully easy to understand but not complete. The online simulator at jtroo.github.io can check configuration validity and simulate input before you touch your real keyboard setup. Live reloading means you can edit the file and see the change without restarting.

The foreground process is the real constraint

The README states it without hedging: running kanata does not start it in a background process, and you must keep the window that starts kanata running to keep kanata active. For a tool that sits between your hands and the operating system, that is a meaningful design decision. If the process dies, your customizations stop applying, and on Linux the process needs sudo to open the device files in the first place.

The README does not document rollback, and it does not describe a supervised mode. Instead it points to community workarounds: a discussion thread for Windows, a comment thread for Linux, and kanata-tray for running from a tray icon. That is an honest answer, but it means startup at login, restart on crash and privilege handling are your problem, not the project's. The wiki link about avoiding sudo on Linux is the documented path if running an input grabber as root is unacceptable in your environment.

There are platform-specific traps too. The README links a platform-known-issues document rather than claiming uniform behaviour, and the Interception driver support on Windows comes with a caveat the project explicitly disclaims: a linked Interception issue is outside the control of this project. The kanata_wintercept.exe binary is the one that uses that driver. If you need the most predictable Windows behaviour, the justfile shows several Windows builds with different input backends, including one using win_sendinput_send_scancodes and one adding win_llhook_read_scancodes, which tells you the choice of backend is a real variable rather than an implementation detail.

What to compare it against

The closest alternative in spirit is QMK, which implements layers and tap-hold in keyboard firmware. The difference is where the logic runs. QMK lives on the microcontroller inside the keyboard, so it works on any machine you plug the board into, including ones where you cannot install software or gain elevated permissions, and it survives reboots with no process to supervise. Kanata runs on the host, so it works with the keyboard you already own and can react to what the operating system is doing, which firmware cannot. The TCP server is the clearest example: external programs can observe layer changes or trigger them, and that is only possible because kanata is a process on the machine.

The cost of that choice is the one described above. Firmware has no window to keep open and no /dev/ permissions to negotiate. If your keyboard is already programmable and you never need host-side integration, kanata is the wrong tool, and the README's own framing about layers will not change that.

Licence and the cost of keeping up

Kanata is LGPL-3.0-only, and the README states that contributions are made under that licence unless explicitly stated otherwise. Two directories are carved out: keyberon is MIT, and interception is MIT or Apache-2.0. The Cargo.toml confirms the package license field as LGPL-3.0-only. If you plan to link the kanata_state_machine library into your own product, the directory-level exceptions matter, because the keyberon code you would be building on is not under the same terms as the rest. This is a description of what the repository says, not legal advice; the LGPL has specific obligations around relinking and source availability that you should have someone qualified read against your distribution model.

On maintenance, the last push to the default branch was on 2026-09-18, and releases include v1.12.0 from 2026-07-05 and a v1.12.1-prerelease-1 from 2026-07-22. The project is not archived. Upgrades are a rebuild plus a config check: the release assets include a kanata.kbd that the README says is tested to work with that release, so diffing your configuration against the shipped sample is the practical way to catch syntax changes. The parser is a separate crate with its own version, which is where most breaking changes to configuration would surface.

Editorial conclusion

Adopt kanata if you want per-key layers, tap-hold and macros configured in a text file, and you accept a foreground process that needs elevated permissions to open the input devices. Do not adopt it if you want a service that starts at boot on its own, or if you need an official macOS driver shipped by this project; the README points at the Karabiner driver in the releases page instead. Before committing, verify that your platform's known issues list does not cover your setup, that your config passes the online simulator, and that live reload picks up edits the way you expect.

Frequently asked questions

How do I install kanata?

You can download a pre-built binary from the releases page, or install from source with cargo install kanata after updating to the latest stable Rust toolchain. On Linux and macOS the README notes that running it may require sudo because kanata opens /dev/ files.

How do I install kanata on Windows?

The README points to pre-built executables on the releases page, and also documents cloning the repository and running cargo build, which produces target\debug\kanata. Some Windows builds use the Interception driver, which corresponds to the kanata_wintercept.exe binary.

How do I install kanata on macOS?

The README says to first install the Karabiner driver by following the macOS documentation on the releases page, then build with cargo and run the binary with sudo, which is needed to gain permission to intercept the keyboard.

How do I use kanata?

Write a configuration file, then start kanata with the --cfg flag pointing at it. Sample configurations live in cfg_samples, the full guide is in docs/config.adoc, and the online simulator can validate a configuration and simulate input before you run it.

What is kanata?

Kanata is a cross-platform software keyboard remapper for Linux, macOS and Windows, written in Rust. It provides multiple layers of key functionality and advanced key behaviour such as tap-hold, macros and unicode output.

Official sources

  1. Issues
  2. jtroo/kanata on GitHub
  3. License: LGPL-3.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/jtroo-kanata.svg)](https://hysenlabs.com/projects/jtroo-kanata)