Installing YazSes on Linux¶
This guide installs the Python daemon as a global command and starts it automatically at login. It targets the reliable batch (transcribe-on-release) configuration. Tested on X11 + PipeWire.
1. Install — one command¶
You do not need to clone the repository — the script fetches everything itself. Paste this. It installs YazSes and every system prerequisite (audio, keystroke injection, clipboard, the input group, and ydotoold on Wayland), then runs yazses doctor so anything missing surfaces during install rather than as silent failure later:
That is the whole install. Skip to §2.
Build prerequisites are handled for you. The script needs
git(it installs the latest code straight from the repo) and a C compiler with the Python headers (evdev, which reads the hotkey, publishes no wheels and is always compiled from source). It checks for all three up front and installs them viaaptif they are missing, instead of failing later inside the build. On a distro withoutaptit stops and names the packages — Fedoragit gcc python3-devel, Archgit base-devel. The Snap is the one channel that needs none of this: it bundles a prebuiltevdev. The APT package does not — itpipx-installs the Python package in its post-install step, so it compilesevdevtoo.
Other install channels (APT, Snap, pipx)
| Channel | Command | Notes | |---|---|---| | **Universal script** (recommended) | `bash <(curl -fsSL https://raw.githubusercontent.com/MSKazemi/yazses/main/install.sh)` | Latest code from git. Installs `uv` if absent. Provisions everything. | | **APT** (Debian/Ubuntu) | `bash <(curl -fsSL https://raw.githubusercontent.com/MSKazemi/yazses/main/install-apt.sh)` | Last tagged release. The script adds the YazSes apt repo, installs the runtime deps, joins you to the `input` group and sets up `ydotoold`; the `.deb`'s post-install step then `pipx`-installs the Python package and enables the user service. | | **Snap** | `sudo snap install yazses``sudo snap connect yazses:audio-record` | The `connect` line is required — without it the snap has no microphone. Snap confinement blocks the global hotkey on some desktops; if hold-to-talk does nothing, use one of the other channels. A snap also ships a **fixed** set of libraries — see [what the snap can and cannot do](#3e-what-the-snap-can-and-cannot-do). | | **pipx** (any distro, Python ≥ 3.11) | `pipx install yazses` | Installs **only** the Python package — needs `build-essential python3-dev` to compile `evdev`, and you must then run `yazses setup` yourself ([§3](#3-installing-by-hand-what-the-installer-did-for-you)). | Already installed and want the newest release?
2. Finish setup¶
Three steps only you can do — the installer prints this same list when it finishes:
# 1. Log out and back in (once — so the `input` group takes effect)
yazses mic-level --set # 2. tune the silence gate to your voice (~4 s)
yazses start # 3. start dictating
The log-out/in is mandatory and one-time. Group membership only refreshes in a new login session — opening another terminal tab is not enough, because it inherits the old session's groups and the hotkey stays dead. To dictate immediately without logging out, bridge the group for one session:
Verify anytime — you want [OK] Keyboard capture, [OK] Microphone, [OK] Injection:
Then hold the hotkey (default right_alt), speak, release — the text types into whatever field has focus. That's it; the rest of this page is reference.
3. Installing by hand (what the installer did for you)¶
Skip this if §1 worked — it is for people installing with pipx, or who want to understand the pieces.
Order matters: the package first, provisioning second. yazses setup is a subcommand of YazSes, so it cannot run until YazSes is installed:
sudo apt install -y pipx build-essential python3-dev # pipx + the evdev build toolchain
pipx install yazses # 1. install the CLI
yazses setup # 2. now provision the system
# then log out and back in (the input-group change needs a fresh login)
yazses setup installs the audio + injection packages, joins you to the input group and sets up ydotoold on Wayland. It is idempotent (safe to re-run — it only fixes what's missing) and finishes by printing the §2 checklist, offering to run the mic calibration for you there and then.
The remaining sub-sections spell out what yazses setup does, for when you want to do each piece yourself.
3a. Runtime dependencies¶
Install every runtime dependency in one command (the APT .deb pulls these in automatically, so skip this if you used install-apt.sh):
What each is for:
| Package | Role | Needed when |
|---|---|---|
libportaudio2 | Audio capture — sounddevice loads it at import | Always (else the daemon crashes on start: OSError: PortAudio library not found) |
xdotool | Text injection (X11) | X11 sessions |
xclip | Clipboard fallback (X11) | X11 sessions |
wtype / ydotool | Text injection (Wayland) | Wayland sessions |
wl-clipboard | Clipboard fallback (Wayland) — provides wl-copy | Wayland sessions |
pipx | Installs the yazses CLI | If installing via pipx |
Installing all of them makes YazSes work whether you log into X11 or Wayland — at runtime YazSes auto-selects the right backend (inject/auto.py). You also need membership in the input group (§3b) and a working microphone (PipeWire/PulseAudio/ALSA).
3b. Add yourself to the input group (required)¶
The hold-to-talk hotkey is read directly from the kernel input devices (/dev/input/event*), which are owned by the input group. If your user is not in that group the daemon cannot detect the hotkey and dictation never starts (yazses doctor reports [FAIL] Keyboard capture: denied).
Then log out and back in (or reboot) — group membership only refreshes on a new login session. Opening another terminal tab is not enough: it inherits the old session's groups, so the hotkey stays dead and yazses doctor still reports [FAIL] Keyboard capture (that line reflects the shell running doctor, not a running daemon). Confirm it took effect:
id -nG | tr ' ' '\n' | grep -x input # should print: input
yazses doctor # should show [OK] Keyboard capture
Do this before starting the daemon (§2). yazses start/restart will warn you if this re-login is still pending. To dictate immediately without logging out, bridge the group for one session:
After a real re-login, a plain yazses start just works — no bridge needed.
3c. Wayland keystroke injection — ydotoold (GNOME/KDE Wayland)¶
How text gets typed depends on your session:
| Session | Injector | Notes |
|---|---|---|
| X11 | xdotool | works out of the box |
| Wayland — wlroots (Sway, Hyprland, …) | wtype | works out of the box |
| Wayland — GNOME / KDE | ydotool + ydotoold | wtype is blocked by Mutter/KWin; ydotool injects at the kernel /dev/uinput level and is the only reliable option |
On GNOME/KDE Wayland you must run the ydotoold daemon, or injection fails with failed to connect socket … .ydotool_socket. yazses setup configures this for you; to do it manually, install the user service:
mkdir -p ~/.config/systemd/user
cp /usr/lib/systemd/user/ydotoold.service ~/.config/systemd/user/ 2>/dev/null \
|| curl -fsSL https://raw.githubusercontent.com/MSKazemi/yazses/main/contrib/ydotoold.service \
-o ~/.config/systemd/user/ydotoold.service
systemctl --user daemon-reload
systemctl --user enable --now ydotoold.service
ls -l /run/user/$(id -u)/.ydotool_socket # socket should now exist
ydotoold runs as your user (no root) because /dev/uinput is owned by the input group (§3b). After this, yazses doctor shows [OK] Injection and [OK] ydotoold.
3d. What gets installed¶
The script, APT and pipx all install five commands into ~/.local/bin (make sure that's on your PATH): yazses, yazses-daemon, yazses-tray, yazses-agent, yazses-overlay. The Snap instead exposes yazses, yazses-daemon, yazses-tray and yazses-overlay on /snap/bin, which is already on your PATH.
If an old
alias yazses=...exists in your shell rc pointing at a previous build, remove it so the installed binary is used.
Working on YazSes itself? Clone the repo and run bash scripts/dev-install.sh — an editable install plus provisioning plus start, in one command.
3e. What the snap can and cannot do¶
A snap ships a fixed set of Python libraries. Its files are read-only, so yazses features enable <name> cannot download anything into it the way the other channels can — whatever is bundled in a revision is all that revision will ever have.
Everything needed for dictation is bundled, plus the capabilities whose libraries fit inside a snap:
| Capability | In the snap? | Why |
|---|---|---|
| Dictation, commands, tray, overlay, mic guard, target guard | ✅ | Part of the base install |
stt-parakeet — higher-accuracy English engine | ✅ | onnx-asr is a base dependency |
meeting, recimport, diarize — Meeting Mode and diarized import | ✅ | sherpa-onnx is bundled |
read-back — spoken read-back of what you dictated | ✅ | kokoro-onnx + soundfile are bundled |
cocktail — Cocktail Filter | ❌ | speechbrain pulls PyTorch (~1 GB) |
llm-cleanup — offline LLM reformatting | ❌ | llama-cpp-python has no PyPI wheels; needs a compiler |
gaze — Glance-Type | ❌ | mediapipe + opencv cost ~110 MB, and it needs a webcam and X11 |
prosody — prosody-aware punctuation | ❌ | praat-parselmouth publishes no aarch64 wheel |
Enabling one of the ❌ rows inside the snap refuses with an explanation rather than failing halfway through — the config is left untouched, so nothing reads as "on" while being unable to work.
To use those four, install through any other channel:
Note that settings do not carry over: the snap keeps config and models under ~/snap/yazses/, an unconfined install under ~/.config/yazses.
4. Start at login¶
The APT install enables this for you. Otherwise it is one command, whichever way you installed YazSes:
That writes a systemd user service pointing at this install, enables it, and starts it. Check it any time:
yazses autostart status # will YazSes be running after the next reboot?
yazses doctor # includes a "Starts at login" check
yazses autostart disable turns it off again.
The service restarts YazSes automatically if it ever crashes — verified by killing it outright, it is back within about five seconds — and gives up after five failures in a minute so a genuinely broken machine leaves a diagnosable state instead of a spin loop.
Display access. X11 injection needs
DISPLAYandXAUTHORITY, which the unit takes from the systemd user manager viaPassEnvironment. GNOME/GDM export them there automatically; confirm withsystemctl --user show-environment | grep DISPLAY. If they are missing, add them to the unit explicitly withsystemctl --user edit yazses.service, or runsystemctl --user import-environment DISPLAY XAUTHORITYfrom inside your session. Without them, dictation runs and the text goes nowhere.
Writing the unit by hand instead
`yazses autostart enable` is the supported path, and it keeps the unit correct across upgrades that move the binary. If you would rather manage it yourself, the unit it installs lives at `~/.config/systemd/user/yazses.service`; `contrib/yazses.service` in the repo is the same file.5. Use it¶
- Focus any text field.
- Hold the hotkey (default
right_alt), speak, release. - The transcript types in once.
6. Tune the silence threshold¶
If dictation does nothing and yazses logs shows Silent audio -- discarding, your speech is below the VAD gate. Measure and set it:
yazses mic-level --set # records ~4s; writes a fitting vad_threshold
systemctl --user restart yazses.service
Re-run whenever your speaking volume changes (e.g. quiet late-night dictation).
7. Manage the service¶
systemctl --user restart yazses.service # after a config change
systemctl --user stop yazses.service # stop
systemctl --user disable --now yazses.service # stop + remove autostart
journalctl --user -u yazses.service -f # live logs via journald
Config lives at ~/.config/yazses/config.toml. See the CLI reference for all commands.
8. Troubleshooting: the hotkey does nothing¶
If holding the key records nothing (no transcript, no overlay reaction), run the health check first — it now pinpoints every common cause in one shot:
Look for these lines and act on any that are not [OK]:
Hotkey device: bound to virtual device …— the daemon is listening on an injector's virtual device (e.g.ydotoold virtual device) instead of your real keyboard, so your keypresses are never seen. Make sure you are in theinputgroup (groups | grep input; if missing, §3b, then log out and back in) so the real keyboard is readable. Fixed in v1.3.3+, which skips virtual devices automatically; older builds need an upgrade.systemd unit: ExecStart=… does not exist— the service points at a binary that isn't there (a leftover from a different install method), so it crash-loops withstatus 203/EXECandyazses start/restartsilently start nothing. Point the unit'sExecStartat your real binary (which yazses-daemon) andsystemctl --user daemon-reload && systemctl --user restart yazses.Install: multiple yazses on PATH …— you have more than one copy installed (e.g. apt + pipx + uv tool). Keep one and uninstall the rest so an upgrade can't leave you running stale code:pipx uninstall yazses,sudo apt remove yazses, oruv tool uninstall yazsesas appropriate.Keyboard capture: FAIL— you are not in theinputgroup; see §3b.
If yazses logs shows Silent audio -- discarding, the key is working but your speech is below the VAD gate — see §6.
Tip: manage the daemon with
systemctl --user restart yazseswhen a systemd unit exists; mixingyazses start(detached) with a systemd unit can leave two daemons fighting over the hotkey, or none running at all.
9. Voice-activity overlay¶
The overlay draws neon "sonar" rings near the cursor that pulse with your voice while you dictate. It is on by default and works out of the box: PySide6 is part of the base install (and bundled in the snap), so there is no extra step. The PySide6 wheels need glibc ≥ 2.28 (Ubuntu 20.04+); on older distros the daemon logs a one-line hint and keeps dictating.
The daemon then auto-launches yazses-overlay on start when a display is present and terminates it on shutdown. If PySide6 isn't installed the daemon logs a one-line hint and keeps dictating — nothing breaks. To turn the overlay off, set [overlay] enabled = false in ~/.config/yazses/config.toml. Run yazses overlay yourself to preview it.
Transparency note (X11): the see-through glow needs a compositing window manager. If you run a bare WM without one, install picom:
Without a compositor the rings still render, just on a small opaque panel.
To autostart it as its own user service instead of letting the daemon spawn it, create ~/.config/systemd/user/yazses-overlay.service with ExecStart=%h/.local/bin/yazses-overlay, Environment=DISPLAY=:0, and After=yazses.service, then systemctl --user enable --now yazses-overlay.