Local, offline voice dictation for Linux, macOS, and Windows — hold a key, speak, release
Project description
NovaVoice
Local, offline voice dictation for Linux, macOS, and Windows. Hold a key, speak, release — the transcribed text appears in whatever app is focused. No cloud, no GPU.
Hold the dictation key (>0.5s) → speak → release → text appears
Powered by faster-whisper (CPU/int8). Works in browsers, terminals, IDEs, chat apps — anywhere the OS lets keystrokes reach the focused window.
Supported platforms
| OS | Hotkey default | Install | Status |
|---|---|---|---|
| Linux | Space |
apt / snap / PPA / pipx / .deb / installer | Stable |
| macOS | Right Option |
.dmg (Homebrew Cask coming) |
Developer preview (unsigned) |
| Windows | Right Ctrl |
.exe installer (winget coming) |
Developer preview (unsigned) |
Why Right Ctrl on Windows, not Right Alt? On many international layouts Right Alt acts as AltGr — used to type
@,€,{},[],\,~, etc. Hijacking it would break normal typing. Right Ctrl is rarely used for typing, so it's the safer default. Every platform's hotkey is configurable inconfig.toml.
Quick install
One-line install on every major OS:
# macOS — via Homebrew tap
brew tap novafabric/novavoice && brew install --cask novavoice
# Windows — via winget (pending PR review at microsoft/winget-pkgs#371427)
winget install NovaFabric.NovaVoice
# Linux — via the apt repo
bash <(curl -fsSL https://raw.githubusercontent.com/novafabric/novavoice/main/install.sh)
# Cross-platform fallback — pip
pipx install novavoice
After install:
| OS | What's left |
|---|---|
| macOS | Right-click → Open the first time (unsigned dev preview); grant Accessibility + Microphone when prompted; hold Right Option to dictate. |
| Windows | If SmartScreen warns, click More info → Run anyway (unsigned dev preview); hold Right Ctrl to dictate. |
| Linux | sudo usermod -aG input "$USER" then re-login; systemctl --user enable --now novavoice.service; hold Space to dictate. |
Full per-OS guides: docs/macos-install.md, docs/windows-install.md. Status of every distribution channel lives in docs/distribution-status.md.
Other channels
If a one-liner above doesn't fit your environment, pick from the platform sections below.
macOS — alternatives
# Direct .dmg download (no Homebrew needed)
# https://github.com/novafabric/novavoice/releases/latest
# Open the .dmg, drag NovaVoice.app into /Applications, right-click → Open the first time.
Windows — alternatives
# Direct .exe download
# https://github.com/novafabric/novavoice/releases/latest
# Click "More info → Run anyway" if SmartScreen warns.
Linux — alternatives
# APT repo (Debian/Ubuntu)
curl -fsSL https://novafabric.github.io/novavoice/apt/KEY.gpg \
| sudo gpg --dearmor -o /usr/share/keyrings/novavoice.gpg
echo "deb [signed-by=/usr/share/keyrings/novavoice.gpg] https://novafabric.github.io/novavoice/apt ./" \
| sudo tee /etc/apt/sources.list.d/novavoice.list
sudo apt update && sudo apt install novavoice
# Launchpad PPA (Ubuntu)
sudo add-apt-repository ppa:novafabric/novavoice
sudo apt update && sudo apt install novavoice
# Snap (works on most distros after `snapd` is installed)
sudo snap install novavoice --classic
# AUR (Arch / Manjaro / EndeavourOS)
yay -S novavoice # any AUR helper
# .deb download
# https://github.com/novafabric/novavoice/releases/latest
sudo apt install ./novavoice_*.deb
# pipx (any Linux)
sudo apt install libportaudio2 xdotool xclip pipx
pipx install novavoice
Usage
NovaVoice runs silently in the background. The same CLI works on every platform.
| Command | What it does |
|---|---|
| Hold the hotkey, speak, release | Transcribe and inject text into focused app |
novavoice status |
Daemon state, model, hotkey, backend, uptime |
novavoice start / stop |
Manage the daemon |
novavoice doctor |
Per-platform prerequisite check |
novavoice inject "hello" |
Type text without recording (debug) |
On macOS and Windows the NovaVoice tray icon changes color to reflect state (idle / recording / transcribing / error).
Configuration
config.toml lives in the platform's standard config dir:
| OS | Path |
|---|---|
| Linux | ~/.config/novavoice/config.toml |
| macOS | ~/Library/Application Support/novavoice/config.toml |
| Windows | %APPDATA%\novavoice\config.toml |
[stt]
model = "tiny.en" # tiny.en (fast) | base.en (more accurate, slower)
[hotkey]
# "auto" → Space (Linux) / right_option (macOS) / right_ctrl (Windows).
# Or pick: "right_ctrl", "right_alt", "right_option", "right_shift",
# "left_ctrl", "left_alt", "left_option", "space", ...
key = "auto"
hold_threshold_ms = 500
[audio]
sample_rate = 16000
max_record_seconds = 90
[tray]
enabled = "auto" # default true on macOS/Windows, false on Linux v0
[general]
log_level = "INFO"
How it works
┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Hotkey hook │──▶│ Audio (16kHz │──▶│ faster-whisper │──▶│ Text injector │
│ (per-OS API) │ │ via │ │ (CPU / int8) │ │ (per-OS API) │
│ │ │ PortAudio) │ │ │ │ │
└──────────────┘ └──────────────┘ └──────────────────┘ └─────────────────┘
│ ▲
└─────────── daemon process ──────────────────────────────────┘
▲
JSON-RPC over Unix socket / named pipe
│
┌─────────┴─────────┐
│ CLI / tray │
└───────────────────┘
Every platform-specific surface (keyboard hook, text injection, autostart, IPC, paths, permissions, tray) lives behind a single Protocol-based abstraction in src/novavoice/platform/. Adding a fifth platform is a matter of writing one more sub-package.
Build from source
git clone https://github.com/novafabric/novavoice
cd novavoice
uv sync
uv run pytest tests/ -v
Platform-specific installers:
# macOS — produces dist/NovaVoice-<v>.dmg
./scripts/build-macos.sh
# Windows — produces dist/NovaVoice-<v>-windows-x64.exe
./scripts/build-windows.ps1
# Linux .deb
./scripts/build-deb.sh
CI builds the unsigned .dmg and .exe on every PR that touches the relevant code paths.
Troubleshooting
novavoice doctor— first stop. Tells you what's missing on the current OS.- macOS: see
docs/macos-install.mdfor Gatekeeper / Accessibility / Microphone. - Windows: see
docs/windows-install.mdfor SmartScreen / antivirus / privacy. - Linux: confirm you're in the
inputgroup; checkjournalctl --user -u novavoice.service -f.
License
Apache 2.0 — see LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file novavoice-0.2.2.tar.gz.
File metadata
- Download URL: novavoice-0.2.2.tar.gz
- Upload date:
- Size: 135.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e47db05c11e6ce1172f859e17a8b41aa5188bdc240fc52797ed418d648f8898b
|
|
| MD5 |
85f938b248e9447281c2f06636a142a8
|
|
| BLAKE2b-256 |
2a3a5a705ece7e8251cda934e3ac0ab8529047229444d92f7f3cedf2f109f950
|
Provenance
The following attestation bundles were made for novavoice-0.2.2.tar.gz:
Publisher:
release.yml on novafabric/novavoice
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
novavoice-0.2.2.tar.gz -
Subject digest:
e47db05c11e6ce1172f859e17a8b41aa5188bdc240fc52797ed418d648f8898b - Sigstore transparency entry: 1472260574
- Sigstore integration time:
-
Permalink:
novafabric/novavoice@2ff04cb5e683a1beea28d7a5716788c9d413e6a9 -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/novafabric
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2ff04cb5e683a1beea28d7a5716788c9d413e6a9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file novavoice-0.2.2-py3-none-any.whl.
File metadata
- Download URL: novavoice-0.2.2-py3-none-any.whl
- Upload date:
- Size: 62.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d757ff67e9f1b75539bc2c7b3ae1587a4ff9eefe3571d82fac4195c97972b4e3
|
|
| MD5 |
a8036daea157d05fa3a0239e4d72b661
|
|
| BLAKE2b-256 |
08ff5e7428c491257e3e8d6003501e6da04e79f1dcdc048910424c66ff01ad53
|
Provenance
The following attestation bundles were made for novavoice-0.2.2-py3-none-any.whl:
Publisher:
release.yml on novafabric/novavoice
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
novavoice-0.2.2-py3-none-any.whl -
Subject digest:
d757ff67e9f1b75539bc2c7b3ae1587a4ff9eefe3571d82fac4195c97972b4e3 - Sigstore transparency entry: 1472260675
- Sigstore integration time:
-
Permalink:
novafabric/novavoice@2ff04cb5e683a1beea28d7a5716788c9d413e6a9 -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/novafabric
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2ff04cb5e683a1beea28d7a5716788c9d413e6a9 -
Trigger Event:
push
-
Statement type: