Library / SDK
boppreh/keyboard avatar
boppreh/keyboard

The keyboard library says it is unmaintained, and its build still runs Python 2

Hook and simulate global keyboard events on Windows and Linux.

3,969 stars450 forksPythonMIT

At a glance

What is it?
boppreh/keyboard hooks and simulates global key events on Windows and Linux with no dependencies and no compiled modules. The repository opens by declaring itself unmaintained, the last tagged release is from 2020, and the Makefile still invokes a Python 2 interpreter for half its test targets.
Who is it for?
This library suits a script that needs to react to a key press regardless of which window has focus, or that needs to type text and trigger combinations programmatically on Windows or Linux, and that can accept a project which may never be updated again. It does not suit anything requiring rootless operation on Linux, since the Linux implementation reads raw device files and the author says that requires root.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 87 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

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

Editorial analysis

The first line of the repository says the project is unmaintained

The opening line of the readme is a warning rather than a pitch. It says the project is currently unmaintained, that it works for many cases, that the author wishes to pick it up again, and that you might encounter friction and limited features using it. That framing is consistent with the dates around it: the newest tagged release is 0.13.5 from March 2020, the two before it are from 2019, and the last push to the default branch is dated 2026-07-10 with no release attached to it. So the code has moved and the published version has not, which means installing from the package index and cloning the branch give you different code. The repository also carries a large open issue count relative to its star count, which is what a project in this state usually looks like: widely used, widely depended on, and nobody answering.

Zero dependencies and no compiled modules, with one exception on macOS

The claim is that the library is pure Python with no C modules to compile and no dependencies at all, trivial to install because you copy the files. The install section backs that up with three routes: a pip install from the package index, a git clone that needs no installation step because the source files are enough, or downloading the archive and extracting it into a project folder. One exception appears in the packaging metadata rather than in the feature list. The install requirements contain a single conditional dependency on a macOS bridge library, marked so that it only applies on that platform, which is what the experimental OS X support in the features depends on. So the zero-dependency claim holds exactly on Windows and Linux, and on macOS you get one extra package. The setup script also notes a packaging quirk: wheel creation breaks on Windows line endings, so the long description is normalised before it is written.

Linux reads raw device files, and the readme says that requires root

The Linux implementation deliberately avoids depending on the display server. It reads the raw device files under the input subsystem directory, and the stated reason is to avoid depending on the graphical stack, but the stated cost is that it requires root. That is the single most consequential line in the limitation list, because it changes what the library is for on Linux: not an ordinary script that watches for a key, but something that has to be run as an administrator to see anything at all. Two consequences follow that the documentation does not spell out. A library imported by a larger application inherits the privilege requirement, so the whole process may need elevation rather than just one call. And an unprivileged parent process cannot delegate the hook to a privileged child without passing the events back, which is a design decision the caller has to make.

Seven limitations, three of them platform-specific and one of them ethical

The known limitations section is unusually complete, and each item points at an issue. Events generated on Windows carry no device identifier, so the device field is empty there. Media keys on Linux may come through with no name, only a scan code, or not at all. Key suppression, which is the ability to block a key from reaching other applications, is available only on Windows. Applications that register their own hooks, some games among them, can swallow every event, and the library will then report nothing, which is a limitation of the platform rather than a bug. One item is not about behaviour at all: the program makes no attempt to hide itself, and the readme says not to use it for keyloggers or gaming bots. That sentence is a deliberate statement about what the library is and is not for, and it is worth reading before deciding whether the project fits your use.

Over SSH the events do not arrive at all

A limitation that is easy to miss because it is about the network rather than the keyboard: an SSH connection forwards only the text typed, not keyboard events. So if you connect to a machine running the library over SSH, the remote side will not see your key events at all. That breaks the most obvious remote use case, which is triggering something on a server or on a small single-board computer you administer remotely, because the events never cross the connection. The same limitation applies to any remote-desktop arrangement that forwards keystrokes rather than sharing the input devices. It is not listed as a bug and has no issue reference, which suggests it is treated as a property of how remote connections work rather than something the library intends to fix. It is also why recording to a file and replaying it is the portable way to move an event sequence between machines, since the file carries the events rather than the keystrokes that produced them:

bash
# Save JSON events to a file until interrupted:
python -m keyboard > events.txt

cat events.txt
# {"event_type": "down", "scan_code": 25, "name": "p", "time": 1622447562.2994788, "is_keypad": false}
# {"event_type": "up", "scan_code": 25, "name": "p", "time": 1622447562.431007, "is_keypad": false}
# ...

# Replay events
python -m keyboard < events.txt

Each line is one event as a JSON object with the direction, the scan code, the key name, a timestamp and whether the key came from the numeric keypad, which is the same shape the recording function returns in memory.

The documented patterns are almost all warnings about busy-waiting

A large section of the documentation is a list of anti-patterns, and the recurring mistake is polling in a loop. Waiting for one key press is shown as a while loop over a state check marked as a mistake because it will consume a full core, with the blocking wait call as the alternative. Repeatedly waiting for the same key shows the same fix plus a hotkey registration. Invoking code when an event happens contrasts passing the result of a print call, which evaluates immediately and then fails when the key is actually pressed, against passing a function. Keeping the program alive is handled the same way, with a spin loop marked as the thing not to do and a blocking call with no argument as the alternative. The message is consistent: every one of these examples works but burns CPU, and the blocking calls exist precisely to avoid that.

The build target still runs a Python 2 interpreter

The Makefile is worth reading before trusting the project on a modern interpreter. Its test target runs four coverage commands, and two of them invoke a Python 2 interpreter, one for the keyboard tests and one for the mouse tests, before the same two run again under a plain python. The report and the HTML coverage output come from the modern runs. So the suite as written exercises both major versions of the language, which is consistent with the feature list claiming support for both, but it also means a Python 2 interpreter has to be installed for the full target to work at all. The build target regenerates the readme from the package docstring using an external script that lives outside the repository, then normalises line endings across the source and markdown files, then builds a source distribution and a wheel and checks them. A release target delegates to a separate script at the repository root.

Editorial conclusion

This library suits a script that needs to react to a key press regardless of which window has focus, or that needs to type text and trigger combinations programmatically on Windows or Linux, and that can accept a project which may never be updated again. It does not suit anything requiring rootless operation on Linux, since the Linux implementation reads raw device files and the author says that requires root. It does not suit a project that needs to suppress a key, because suppression is documented as Windows-only, or one that expects a device identifier on Windows, where events arrive with none. Before adopting it, read the limitation list in full rather than the feature list, decide whether root on Linux is available to you, and remember that installing from the package index gives you version 0.13.5 while the default branch has moved since, so pin deliberately.

Frequently asked questions

How do I install the keyboard library for Python?

Run `pip install keyboard` from the package index, or clone the repository and use the source files directly with no installation step, or download the archive and extract it into your project folder. On macOS a conditional dependency on a bridge library is installed; Windows and Linux have no dependencies at all.

Does the keyboard library need root on Linux?

Yes. The Linux implementation reads the raw device files under the input subsystem directory in order to avoid depending on the display server, and the documentation states that this requires root. Windows does not have that requirement, and key suppression is available on Windows only.

Is the keyboard library still maintained?

The repository states at the top that the project is currently unmaintained, that it works for many cases, and that the author wishes to pick it up again. The newest tagged release is v0.13.5 from March 2020, while the last push to the default branch is dated 2026-07-10, so the published version and the branch are not the same code.

Official sources

  1. boppreh/keyboard on GitHub
  2. Issues
  3. License: MIT
  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/boppreh-keyboard.svg)](https://hysenlabs.com/projects/boppreh-keyboard)