Speedy
I spend most of my working day in the terminal, and I love using different TUIs like OpenCode, lazygit, lazydocker, and k9s. Between writing code in Neovim, moving around tmux, working with Git, taking notes, planning projects, documenting progress, learning, and prompting agents, I am constantly typing.
At some point, I became curious about how many keys I press during a normal day and which hours are the most active. Because most of the time I'm typing means I'm doing something or learning so could be very nice to know how much active I am.
I was not interested in knowing what I typed. I already know what I am typing at that moment 😅. I only wanted the numbers so I could track my activity and compare it over time.
So I built Speedy, a small terminal application written in Rust that counts keyboard activity and reports some simple analytics.
The idea
The idea was straightforward:
- listen for keyboard presses
- count them by day and hour
- store the counts locally
- display the results in the terminal
The important part is that Speedy does not store which keys were pressed.
It does not record words, commands, passwords, applications, or websites. A key press is immediately converted into a number, and only that number is kept.
This matters because any application listening to keyboard events can easily sound like a keylogger. Speedy is intentionally limited to activity counts, and everything stays on the local machine.
The app
I wanted the interface to feel more like an odometer than a traditional analytics dashboard.
Speedy has four different views: Live, Daily, Hourly, and Records.
Live
The Live view gives me a quick overview of today’s activity, including my current typing speed and progress toward the daily goal. The target is currently fixed, but I want to make it customizable. I opened an issue on GitHub, so if you are interested in contributing to Speedy, this could be a good place to start.
Daily
The Daily view shows how my activity has changed over the last seven days and compares it with the previous week.
Hourly
The Hourly view shows when I am most active and how my keyboard activity is distributed throughout the day.
Records
The Records view gives me a longer-term picture using all-time totals, recent averages, trends, and my usual working rhythm.
How it works
Speedy is written in Rust and uses evdev to count physical key presses on Linux. Releases and automatic repeats are ignored, while hourly totals are stored locally in SQLite.
The dashboard is built with Ratatui and Crossterm. Speedy runs its recorder in the background, so closing the dashboard does not stop the count. To stop it manually, run:
speedy --stop
Running it
With Rust installed:
git clone https://github.com/4m1z/speedy.git
cd speedy
cargo install --path .
speedy
Speedy needs permission to read /dev/input/. On Arch-based systems, add your user to the input group, then log out and back in:
sudo usermod -aG input "$USER"
All collected data remains on the local machine.
Integrating it with Omarchy
Finally, I wanted to integrate Speedy into my Omarchy setup.
Instead of opening a terminal and typing the command every time, I added a Hyprland keybinding to ~/.config/hypr/bindings.conf:
bindd = SUPER SHIFT, I, Speedy, exec, omarchy-launch-or-focus Speedy "uwsm app -- alacritty --class Speedy -T Speedy -o window.padding.x=12 -o window.padding.y=12 -e sg input -c /home/NAME/.cargo/bin/speedy"
Now Super + Shift + I opens Speedy in Alacritty. If the window is already open, Omarchy focuses it instead of starting another one.
I gave the window its own Speedy class and title, added some terminal padding, and used sg input so the process runs with the input-device permissions it needs.
Hyprland reloads the binding after the configuration is saved. If needed, it can also be reloaded manually:
hyprctl reload
This makes Speedy feel like part of my desktop instead of a separate command I need to remember.
The project is available on GitHub.