Local-first dictation for X11 and Wayland: hold Right Alt, speak, release, and the text is typed into the focused app. Recording, speech recognition (Phonon-2, with Whisper as the fallback), optional cleanup and text insertion all run on this computer. For model setup and first-run checks across platforms, see the first-run guide.
- Push-to-talk or toggle: hold Right Alt to dictate, or tap it to start and tap again to stop.
- Types into the focused app through
/dev/uinput, and restores your clipboard afterwards. If typing isn't possible, the text is put on the clipboard instead and the panel says so. - On-device recognition: Phonon-2 (English, on CrispASR) once you download it, and Whisper (whisper.cpp) for every other case. Optional cleanup by the on-device S1-mini model (downloaded from Settings) or by a local Ollama / LM Studio server.
- Dictation panel and tray that follow the macOS app: a small waveform pill at the top of the screen, a live panel while you dictate, searchable transcript history saved on this computer, and a status tray icon.
- Works across desktops: GNOME, KDE Plasma, Hyprland, Sway and X11 window managers.
- Android companion discovery: when Avahi and a network-reachable SSH server are available, Talkies advertises this computer so the Android companion can find it without manual host entry.
talkies doctorchecks audio, microphone, hotkey, typing, clipboard, tray and model, and tells you how to fix anything that isn't ready.
Ollama and LM Studio cleanup only accept localhost, 127.0.0.0/8 or ::1 endpoints. Remote
endpoints are rejected and HTTP redirects are disabled, so transcripts never leave the machine.
Besides the model downloads you ask for, Talkies makes no outbound Internet requests except the update check described in Updates, which sends no user data and can be turned off. When enabled, companion discovery is a local-network DNS-SD announcement only.
For Android companion discovery, install and run Avahi (avahi-daemon and
avahi-publish-service) and enable an SSH server on the desktop. Talkies publishes the SSH service
only while its daemon is running and only when ss reports a non-loopback SSH listener. It advertises
the service as _ssh._tcp with a talkies=1 marker, allowing the Android companion to prefill the
host and port. The default SSH port is 22; set TALKIES_SSH_PORT in the Talkies daemon environment
when sshd listens on a different port. Discovery is optional and does not affect Talkies when Avahi,
ss, or SSH is unavailable.
Every release on GitHub Releases ships the same x86_64 build in several formats. It bundles Talkies' Whisper/llama.cpp runtimes, so only standard desktop libraries (GTK 4, PulseAudio client or pipewire-pulse, SQLite, D-Bus) come from your distribution. Minimum: glibc 2.35 and GTK 4.6 (Ubuntu 22.04, Debian 12, RHEL 9 or newer) and a CPU with AVX2 (2013 or newer). CI installs each package on the distributions below before every release.
| Distribution | Package | Install |
|---|---|---|
| Ubuntu 22.04+, Debian 12+, Mint, Pop!_OS | .deb |
sudo apt install ./Talkies-Linux-<version>.deb |
| Fedora, RHEL / Alma / Rocky 9+ | .rpm |
sudo dnf install ./Talkies-Linux-<version>.rpm |
| openSUSE Tumbleweed / Leap | .rpm |
sudo zypper install --allow-unsigned-rpm ./Talkies-Linux-<version>.rpm |
| Arch, Manjaro, EndeavourOS | .pkg.tar.zst or AUR PKGBUILD |
sudo pacman -U ./Talkies-Linux-<version>.pkg.tar.zst |
| Gentoo | overlay: talkies (source) or talkies-bin |
see below |
| Anything else (glibc) | .tar.gz |
tar xf Talkies-Linux-<version>.tar.gz && sudo ./talkies-*/install.sh |
Then start Talkies from your app menu (or run talkies daemon) and run talkies doctor if
anything does not work. The first start downloads the Whisper model once (about 150 MB); after that
Talkies runs fully offline. Phonon-2 (674 MB) is downloaded only when you ask for it, under
Settings > Transcription or with talkies models.
The packages install a udev rule that gives the logged-in user access to /dev/uinput, which Talkies
uses to type text. On Wayland, the Right Alt hotkey additionally needs read access to keyboards:
sudo usermod -aG input $USER, then log in again (or bind talkies-hotkey.sh in your compositor).
Arch (AUR-style build). Download PKGBUILD from the release and run makepkg -si next to it.
Gentoo. Each release ships a ready overlay (talkies-gentoo-overlay-<version>.tar.gz, with
Manifests) holding two packages:
app-accessibility/talkiesbuilds from source: the pinned whisper.cpp / llama.cpp and the exact Zig compiler the release was tested with (Gentoo does not package Zig master; it is used at build time only).USE=nativebuilds Talkies and ggml for your CPU instead of the portable baseline.app-accessibility/talkies-bininstalls the prebuilt release under/opt/talkies.
doas mkdir -p /var/db/repos/talkies /etc/portage/repos.conf
doas tar xf talkies-gentoo-overlay-<version>.tar.gz -C /var/db/repos/talkies
printf '[talkies]\nlocation = /var/db/repos/talkies\n' | doas tee /etc/portage/repos.conf/talkies.conf
echo 'app-accessibility/talkies ~amd64' | doas tee /etc/portage/package.accept_keywords/talkies
doas emerge --ask app-accessibility/talkies # or talkies-bin; USE="X wayland" pull xclip / wl-clipboardUser-only install (no root). ./talkies-*/install.sh without sudo installs into ~/.local;
typing into apps then needs /dev/uinput access, which the root install sets up.
Uninstall. Use your package manager (apt remove talkies, dnf remove talkies,
pacman -R talkies, emerge --depclean talkies) or ./talkies-*/install.sh --uninstall.
Settings (~/.config/talkies), models and transcript history (~/.local/share/talkies) are kept.
Start Talkies from your app menu, or run talkies daemon (add it to your session's autostart, or
turn on Launch at login in Settings).
Talkies rests as a small waveform pill at the top centre of the screen. Click it to open the panel.
| State | What you see |
|---|---|
| Ready | Green dot, "Ready to dictate", your hotkey hint, and the last transcript |
| Recording | Red dot, elapsed time, and a live scrolling waveform of your voice |
| Transcribing / cleaning / inserting | Animated waveform and a spinner while the work runs on-device |
| Done | "Text insertion complete" with a Copy text button; the panel collapses after 2.5 seconds |
| No speech, manual paste, errors | Stays open with the reason and what to do; move the pointer away to dismiss |
The clock button opens Transcript History: your saved transcripts, newest first, 50 at a time
(Show older loads more). Type in the search field to filter them (case-insensitive), and use the
buttons on each entry to copy or delete it. Clear all (click twice to confirm) deletes every saved
transcript. The search field is the only time the panel takes keyboard focus; on compositors that
never focus it (for example with the Hyprland rules), use talkies history --search instead.
Use mini window in Settings switches to a compact 360-pixel panel.
While Save transcript history (Settings > General, on by default) is on, every final transcript,
the text that was typed or copied, is saved to
${XDG_DATA_HOME:-$HOME/.local/share}/talkies/history.sqlite. The directory is private (0700) and
the file is readable only by you (0600). Transcripts are kept until you delete them; nothing expires
and nothing leaves the computer. Turning the setting off stops saving but keeps what is already
saved; entries from the current session are still shown until Talkies restarts. Transcript text is
never written to the log.
Each entry also records the recognizer output before cleanup (when cleanup changed it), the audio
length, the speech engine (phonon or whisper) and the language. The SQLite schema
(linux/src/app/history_schema.sql, PRAGMA user_version = 1) is shared with the other Talkies
clients; every row has a random UUID so history can later be synced between devices.
talkies history # newest 50
talkies history --search invoice --limit 200
talkies history --json # every column, including uuid
talkies history clear # delete everything (then VACUUM)The tray icon shows what Talkies is doing: ready, loading the model, recording, transcribing, polishing, inserting, finished, or needs attention. Hover it for details. Click it to open or collapse the panel, middle-click to start or stop recording, and right-click for Open Talkies, Settings... and Quit Talkies. It works with any StatusNotifierItem host: KDE Plasma, GNOME with the AppIndicator extension, waybar, AGS and similar bars.
Settings has five pages:
- General: mini window, launch at login, transcript history, updates, push-to-talk threshold, voice assistant mode.
- Transcription: microphone, speech engine (Automatic, Phonon-2 or Whisper), the Phonon-2 download, Whisper model and language, personal vocabulary (one name or uncommon word per line, used as Whisper recognition hints).
- Enhancement: off, S1-mini (download and manage the model here, then pick writing style, structure and context), Ollama or LM Studio.
- Output: type at the cursor or copy only, paste shortcut, clipboard restore.
- Advanced: config file location and developer options.
A status card at the top of Settings shows the same checks as talkies doctor.
Talkies tries the recognizers in order and uses the first one that works:
- Phonon-2, Fermion Research's compressed NVIDIA Parakeet TDT 0.6B v3 (English only, weights CC-BY-4.0), run by CrispASR.
- Whisper (whisper.cpp), the fallback. It is always available.
speech_engine |
Uses Phonon-2 when | Otherwise |
|---|---|---|
auto (default) |
it is downloaded and the language is English (en, en-US, ...) |
Whisper |
phonon |
it is downloaded and the language is English or auto |
Whisper |
whisper |
never | Whisper |
Talkies also falls back to Whisper for a dictation when Phonon-2 fails to load or to transcribe it.
After a load failure, Talkies stops retrying Phonon-2 until you change the speech settings or
restart. Choosing Phonon-2 in Settings starts its download. Automatic never downloads
anything. Phonon-2 ignores the personal vocabulary, and talkies transcribe --format vtt|srt always
uses Whisper because it needs Whisper's segment timestamps. talkies doctor and the Settings status
card show which engine is in use and why.
-
X11: Right Alt works out of the box.
-
Wayland (GNOME, KDE, Hyprland, Sway): Talkies reads Right Alt directly from the keyboard device, which needs read access to keyboards:
sudo usermod -aG input "$USER" # then log out and back in
If you'd rather not join the
inputgroup, bind a key in your compositor to the bundled helper,/usr/share/talkies/talkies-hotkey.sh(down/upfor push-to-talk,togglefor tap-to-toggle). For Hyprland:exec-once = talkies daemon bind = , Alt_R, exec, /usr/share/talkies/talkies-hotkey.sh down bindr = ALT, Alt_R, exec, /usr/share/talkies/talkies-hotkey.sh up # or a toggle on any chord: # bind = SUPER ALT, T, exec, /usr/share/talkies/talkies-hotkey.sh toggle
On Hyprland the daemon also sets the window rules for its panel and Settings window at startup.
/usr/share/talkies/hyprland-rules.confhas the same rules if you prefer them in your config.
Talkies checks GitHub Releases for a newer Linux build about a minute after the daemon starts and
then once a day, on a background thread. The check is a single HTTPS GET of the release's
BUILD-INFO.txt (with curl); nothing about you, your settings or your transcripts is sent, and it
has nothing to do with speech recognition, which stays on this computer.
- Builds from the rolling
latestprerelease keep the same version number on every push to master, so they compare the commit they were built from with the one inBUILD-INFO.txt. - Builds of a tagged release (
vX.Y.Z, and distro builds such as the Gentoo ebuild) compare version numbers with the newest stable release. - Development and CI builds never check.
When an update exists, Talkies shows a desktop notification once and the Updates row in
Settings > General says what to do. Nothing is installed until you click Install and Restart
(or confirm talkies update). The download goes to ~/.cache/talkies/updates/ and is used only
if its SHA-256 matches the release's SHA256SUMS; otherwise it is deleted and the update is
refused. How it is installed depends on how you installed Talkies:
| Installed with | What the update does |
|---|---|
install.sh into a prefix you own (e.g. ~/.local) |
Swaps <prefix>/lib/talkies for the new version in one rename, refreshes the menu entry and icons, then restarts the daemon |
sudo ./install.sh (e.g. /usr/local) |
Runs the verified tarball's install.sh through pkexec |
.deb / .rpm / Arch package |
Never touches package files itself: after you approve, pkexec runs apt install, dnf install / zypper install, or pacman -U on the verified package |
AUR talkies-bin |
Notification only: update it with your AUR helper |
| Gentoo overlay | Notification only: sync the overlay and emerge --update |
For the pkexec installs, root copies the download into a private directory and checks its
SHA-256 again before the package manager reads it. After installing, the daemon restarts itself
once no dictation is running: through systemctl --user restart when a systemd user unit runs it,
otherwise by starting the new binary in place. install.sh records itself in
<prefix>/lib/talkies/install-method so the updater can tell its files from a package manager's.
To turn the checks off, switch off Check for updates automatically in Settings, set
check_automatically = false under [updates], or set TALKIES_NO_UPDATE_CHECK=1 in the
daemon's environment (this also blocks Check Now and talkies update).
talkies update --check # what is installed, how, and whether a newer build exists
talkies update # the same, then download, verify and install after you confirmSettings are saved to ~/.config/talkies/config.toml. Everything is editable in the Settings
window; the file is plain TOML if you prefer editing it directly:
[general]
push_to_talk_threshold = 0.15 # hold longer than this (s) for push-to-talk; quicker taps toggle
show_hud = true # dictation panel
mini_window = false # compact panel
sounds = false # start/stop sounds
voice_assistant_mode = false # speak the result (spd-say / espeak-ng) instead of typing it
[audio]
device = "" # PulseAudio/PipeWire source; empty = default (talkies audio-list)
[transcription]
speech_engine = "auto" # auto | phonon | whisper (see Speech engines)
model = "base" # Whisper model: tiny | base | small | medium | large
language = "en" # Phonon-2 needs English; other languages use Whisper
vocabulary_prompt = "Talkies, S1-mini" # Whisper recognition hints, max 400 characters
[enhancement]
provider = "none" # none | s1_mini | ollama | lm_studio
[cleanup] # S1-mini
style = "semi_formal" # casual | semi_casual | semi_formal
structure = "prose" # prose | lists
context = "general" # general | email
[output]
auto_paste = true # type at the cursor; false = copy to clipboard only
restore_clipboard = true
[history]
save = true # keep transcripts in history.sqlite until you delete them
[updates]
check_automatically = true # look for a newer build at startup and daily (see Updates)
[vad]
enabled = true # trim silence before transcription[ollama] and [lm_studio] hold the model, endpoint (loopback only) and sampling settings for
those providers.
| Command | What it does |
|---|---|
talkies daemon |
Run Talkies: panel, tray and hotkey |
talkies doctor |
Check this system and suggest fixes |
talkies models |
Download Phonon-2 (unless speech_engine = "whisper") and the configured Whisper model |
talkies audio-list / audio-set <device> |
List or choose the microphone |
talkies audio |
Record a 5-second test |
talkies quick |
Record, transcribe and type once, without the daemon |
talkies transcribe <file.wav> --format txt|vtt|srt --output <file> |
Export a transcript with timestamps |
talkies history [--search Q] [--limit N] [--json] |
List saved transcripts, newest first |
talkies history clear |
Delete every saved transcript |
talkies update [--check] |
Check GitHub Releases for a newer build; without --check, install it after confirmation |
talkies config |
Print the current configuration |
talkies --version |
Print the version |
Whisper models are pinned to a specific upstream revision,
checked against their exact size and SHA-256, and verified before each load; verified models work
offline. They live in ~/.local/share/talkies/models/.
Phonon-2 is pinned the same way, to cstr/phonon2-GGUF
at revision 3ed3e6ad: phonon2-q8_0.gguf (674,342,560 bytes) plus its LICENSE and NOTICE,
each with an exact size and SHA-256. They are stored in
~/.local/share/talkies/models/phonon2-<revision>/ and verified before each load. Loading never
downloads anything and nothing falls back to a network service.
If a command exits with an unhandled error, Talkies best-effort writes a local
report containing the error name, timestamp, and available Zig error-return
stack addresses. Reports are stored under
${XDG_DATA_HOME:-$HOME/.local/share}/talkies/diagnostics/, with private
directory and file permissions, a 32 KiB report limit, and five rotating files.
Reports are never uploaded. To remove them, quit Talkies and run:
rm -rf "${XDG_DATA_HOME:-$HOME/.local/share}/talkies/diagnostics"Needs Zig master (0.18.0-dev), GTK 4, PulseAudio (or pipewire-pulse), SQLite, X11 and D-Bus
development files, plus the pinned whisper.cpp and llama.cpp that build-native-deps.sh builds.
zig build fetches the pinned CrispASR v0.8.43 release libraries for x86_64 or aarch64 (hash-pinned
in build.zig.zon) and installs them into zig-out/lib/crispasr/. Pass -Dcrispasr=false to build
without them, for example offline. Talkies then uses Whisper only.
packaging/linux/build-native-deps.sh # once; installs into /usr/local
cd linux
zig build -Doptimize=ReleaseSafe # zig-out/bin/talkies
zig build test # unit tests for every layer
scripts/install.sh --restart # developer install, restarts the daemonOn Gentoo, app-accessibility/talkies from the release overlay does all of this for you.
To build the release packages locally, run
zig build -Doptimize=ReleaseSafe -Dcpu=x86_64_v2 -Dversion=X.Y.Z (release CI also passes
-Dcommit=<sha> -Dchannel=<latest|vX.Y.Z> for the updater) and then
VERSION=vX.Y.Z APP_VERSION=X.Y.Z packaging/linux/package.sh. The output goes to linux/dist/, and
packaging/linux/README.md describes the pipeline.
The build is split by how often each part changes:
| Binary | Source | Contents |
|---|---|---|
talkies |
src/app, src/engine, src/core |
Daemon, config, audio, Whisper, hotkey, text insertion |
libtalkies-ui.so |
src/ui |
GTK 4 panel, Settings, tray (StatusNotifierItem over D-Bus) |
libtalkies-native.so |
src/native |
S1-mini cleanup on llama.cpp; the CrispASR loader for Phonon-2 |
bundled libwhisper, libllama, libggml* |
deps.env |
Pinned runtimes, shared by both models |
lib/crispasr/ |
build.zig.zon |
CrispASR with its own ggml, BLAS and OpenMP libraries, plus their notices |
All of these resolve each other through $ORIGIN, so the installed tree is relocatable.
CrispASR ships its own ggml under the same sonames as the bundled one, and it exports whisper_*
symbols. Talkies therefore never links it. libtalkies-native.so loads lib/crispasr/ with
dlmopen into a separate dynamic-linker namespace, so neither library can bind to the other's
symbols. This needs glibc. TALKIES_CRISPASR_DIR points Talkies at a different copy of the runtime.
Set TALKIES_TEST_PHONON=1 to run the Phonon-2 JFK test once the model is installed.
Start with talkies doctor; it names the problem and the fix. Common cases:
- Text isn't typed into apps. The packages install a udev rule for
/dev/uinput; log out and in once after installing. A manual install needs the rule fromlinux/data/70-talkies-uinput.rules. Until then Talkies copies the text to the clipboard and tells you to paste it. - Right Alt does nothing on Wayland. Join the
inputgroup (see above), or bind the hotkey helper in your compositor. - No audio or "Microphone unavailable". Make sure PipeWire (with pipewire-pulse) or PulseAudio
is running, then pick the microphone with
talkies audio-listandtalkies audio-set, or in Settings. - No tray icon. Your panel needs a StatusNotifierItem host (on GNOME, the AppIndicator extension). The hotkey and panel work without one.
- "Address already in use" when starting. Another daemon is running. Quit it from the tray, or
run
linux/scripts/cleanup.shin a source checkout. - "Phonon-2 could not load".
talkies doctorshows the reason. The CrispASR runtime has to be inlib/crispasr/next to thetalkiesbinary (or inTALKIES_CRISPASR_DIR). Until it loads, Talkies uses Whisper. To stop trying Phonon-2, setspeech_engine = "whisper". - GPU. Whisper (in the packaged build) and Phonon-2 run on the CPU (AVX2). A source build can enable whisper.cpp's
Vulkan or CUDA backends in
build-native-deps.sh.
See the repository's LICENSE file. Bundled third-party licenses ship in
/usr/share/doc/talkies/licenses/.