Handy CJ Pais
winget install --id=cjpais.Handy -e A free, open source, and extensible speech-to-text application that works completely offline.
winget install --id=cjpais.Handy -e A free, open source, and extensible speech-to-text application that works completely offline.
A free, open source, and extensible speech-to-text application that works completely offline.
Handy is a cross-platform desktop application that provides simple, privacy-focused speech transcription. Press a shortcut, speak, and have your words appear in any text field. This happens on your own computer without sending any information to the cloud.
Handy was created to fill the gap for a truly open source, extensible speech-to-text tool. As stated on handy.computer:
Handy isn't trying to be the best speech-to-text app—it's trying to be the most forkable one.
The process is entirely local:
brew install --cask handyFor detailed build instructions including platform-specific requirements, see BUILD.md.
Handy is built as a Tauri application combining:
whisper-rs: Local speech recognition with Whisper modelstranscription-rs: CPU-optimized speech recognition with Parakeet modelscpal: Cross-platform audio I/Ovad-rs: Voice Activity Detectionrdev: Global keyboard shortcuts and system eventsrubato: Audio resamplingHandy includes an advanced debug mode for development and troubleshooting. Access it by pressing:
Cmd+Shift+DCtrl+Shift+DHandy supports command-line flags for controlling a running instance and customizing startup behavior. These work on all platforms (macOS, Windows, Linux).
Remote control flags (sent to an already-running instance via the single-instance plugin):
handy --toggle-transcription # Toggle recording on/off
handy --toggle-post-process # Toggle recording with post-processing on/off
handy --cancel # Cancel the current operation
Startup flags:
handy --start-hidden # Start without showing the main window
handy --no-tray # Start without the system tray icon
handy --debug # Enable debug mode with verbose logging
handy --help # Show all available flags
Flags can be combined for autostart scenarios:
handy --start-hidden --no-tray
> macOS tip: When Handy is installed as an app bundle, invoke the binary directly:
>
> bash > /Applications/Handy.app/Contents/MacOS/Handy --toggle-transcription >
This project is actively being developed and has some known issues. We believe in transparency about the current state:
Whisper Model Crashes:
Wayland Support (Linux):
wtype or dotool for text input to work correctly (see Linux Notes below for installation)Text Input Tools:
For reliable text input on Linux, install the appropriate tool for your display server:
| Display Server | Recommended Tool | Install Command |
|---|---|---|
| X11 | xdotool | sudo apt install xdotool |
| Wayland | wtype | sudo apt install wtype |
| Both | dotool | sudo apt install dotool (requires input group) |
xdotool for both direct typing and clipboard paste shortcutswtype (preferred) or dotool for text input to work correctlyinput group: sudo usermod -aG input $USER (then log out and back in)Without these tools, Handy falls back to enigo which may have limited compatibility, especially on Wayland.
Other Notes:
Runtime library dependency (libgtk-layer-shell.so.0):
Handy links gtk-layer-shell on Linux. If startup fails with error while loading shared libraries: libgtk-layer-shell.so.0, install the runtime package for your distro:
| Distro | Package to install | Example command |
|---|---|---|
| Ubuntu/Debian | libgtk-layer-shell0 | sudo apt install libgtk-layer-shell0 |
| Fedora/RHEL | gtk-layer-shell | sudo dnf install gtk-layer-shell |
| Arch Linux | gtk-layer-shell | sudo pacman -S gtk-layer-shell |
For building from source on Ubuntu/Debian, you may also need libgtk-layer-shell-dev.
The recording overlay is disabled by default on Linux (Overlay Position: None) because certain compositors treat it as the active window. When the overlay is visible it can steal focus, which prevents Handy from pasting back into the application that triggered transcription. If you enable the overlay anyway, be aware that clipboard-based pasting might fail or end up in the wrong window.
If you are having trouble with the app, running with the environment variable WEBKIT_DISABLE_DMABUF_RENDERER=1 may help
Global keyboard shortcuts (Wayland): On Wayland, system-level shortcuts must be configured through your desktop environment or window manager. Use the CLI flags as the command for your custom shortcut.
GNOME:
Toggle Handy Transcriptionhandy --toggle-transcriptionSuper+O)KDE Plasma:
The following are recommendations for running Handy on your own machine. If you don't meet the system requirements, the performance of the application may be degraded. We are working on improving the performance across all kinds of computers and hardware.
For Whisper Models:
For Parakeet V3 Model:
We're actively working on several features and improvements. Contributions and feedback are welcome!
Debug Logging:
macOS Keyboard Improvements:
Opt-in Analytics:
Settings Refactoring:
Tauri Commands Cleanup:
If you're behind a proxy, firewall, or in a restricted network environment where Handy cannot download models automatically, you can manually download and install them. The URLs are publicly accessible from any browser.
Cmd+Shift+D to open debug menuCtrl+Shift+D to open debug menuThe typical paths are:
~/Library/Application Support/com.pais.handy/C:\Users\{username}\AppData\Roaming\com.pais.handy\~/.config/com.pais.handy/Inside your app data directory, create a models folder if it doesn't already exist:
# macOS/Linux
mkdir -p ~/Library/Application\ Support/com.pais.handy/models
# Windows (PowerShell)
New-Item -ItemType Directory -Force -Path "$env:APPDATA\com.pais.handy\models"
Download the models you want from below
Whisper Models (single .bin files):
https://blob.handy.computer/ggml-small.binhttps://blob.handy.computer/whisper-medium-q4_1.binhttps://blob.handy.computer/ggml-large-v3-turbo.binhttps://blob.handy.computer/ggml-large-v3-q5_0.binParakeet Models (compressed archives):
https://blob.handy.computer/parakeet-v2-int8.tar.gzhttps://blob.handy.computer/parakeet-v3-int8.tar.gzFor Whisper Models (.bin files):
Simply place the .bin file directly into the models directory:
{app_data_dir}/models/
├── ggml-small.bin
├── whisper-medium-q4_1.bin
├── ggml-large-v3-turbo.bin
└── ggml-large-v3-q5_0.bin
For Parakeet Models (.tar.gz archives):
.tar.gz filemodels folderparakeet-tdt-0.6b-v2-int8parakeet-tdt-0.6b-v3-int8Final structure should look like:
{app_data_dir}/models/
├── parakeet-tdt-0.6b-v2-int8/ (directory with model files inside)
│ ├── (model files)
│ └── (config files)
└── parakeet-tdt-0.6b-v3-int8/ (directory with model files inside)
├── (model files)
└── (config files)
Important Notes:
.bin files for Whisper models—use the exact filenames from the download URLsHandy can auto-discover custom Whisper GGML models placed in the models directory. This is useful for users who want to use fine-tuned or community models not included in the default model list.
How to use:
.bin format (e.g., from Hugging Face).bin file in your models directory (see paths above)Important:
.bin file)my-custom-model.bin → "My Custom Model")The goal is to create both a useful tool and a foundation for others to build upon—a well-patterned, simple codebase that serves the community.
MIT License - see LICENSE file for details.
"Your search for the right speech-to-text tool can end here—not because Handy is perfect, but because you can make it perfect for you."
Toggle Handy Transcriptionhandy --toggle-transcriptionSway / i3:
Add to your config file (~/.config/sway/config or ~/.config/i3/config):
bindsym $mod+o exec handy --toggle-transcription
Hyprland:
Add to your config file (~/.config/hypr/hyprland.conf):
bind = $mainMod, O, exec, handy --toggle-transcription
You can also manage global shortcuts outside of Handy via Unix signals, which lets Wayland window managers or other hotkey daemons keep ownership of keybindings:
| Signal | Action | Example |
|---|---|---|
SIGUSR2 | Toggle transcription | pkill -USR2 -n handy |
SIGUSR1 | Toggle transcription with post-processing | pkill -USR1 -n handy |
Example Sway config:
bindsym $mod+o exec pkill -USR2 -n handy
bindsym $mod+p exec pkill -USR1 -n handy
pkill here simply delivers the signal—it does not terminate the process.