Skip to content

voxtype: Configuration & CLI

Configuration lives at ~/.config/voxtype/config.toml (voxtype also reads a legacy ~/.config/voice-type/config.toml if it exists and the voxtype one doesn’t — a carryover from when the tool shipped as voice-type).

You rarely need CLI flags. Every runtime flag is just an override of a config key (the exceptions are --config, which points at a different file, and the setup/init --force flag), so the intended workflow is: put your preferences in the config once, then your daily command is plain voxtype — flags exist for one-off experiments (e.g. trying another engine) and always win over the file. The config also holds keys that have no flag at all (wake_word_aliases, submit_phrases, sound names, paste_hotkey, cancel_hotkey, copy_to_clipboard, parakeet_threads, …), so the file is the complete interface; the flags are a subset.

Two ways to create that file:

Terminal window
voxtype setup # interactive walkthrough — asks, then writes
voxtype init # write a fully commented sample to edit by hand
voxtype init --force # overwrite an existing sample

voxtype setup is the quickest start: it asks a short series of explained questions (engine, mode, segmentation, hotkey, wake word, and optional extras), validates your choices, and writes a ready-to-use config — you can record the hotkey live during the walkthrough. init instead drops a fully commented sample (like the reference below) for hand-editing.

Three settings combine to define how voxtype behaves, and they answer different questions:

  • modewhen is it listening? toggle: only between two presses of the hotkey. wake: always passively listening for the wake word (hotkey works as an override). vad: dictating from the moment it starts.
  • segmentationwhen does text appear? See “When does the text appear?” below — this is the axis people mean when they ask about “streaming” dictation. (Mostly independent, with one tie: hold needs a parakeet engine in toggle mode; otherwise voxtype uses vad.)
  • enginewhat transcribes it? Pure speed/accuracy/platform trade-off; see the engine table below. Any engine works with any mode.

Dictation tools differ in how immediately the transcript shows up. The spectrum, from most to least immediate:

  1. Word-by-word streaming (Apple-dictation style: words materialize and self-correct as you speak). voxtype deliberately does not do this into your apps: revising already-typed text in another application means blindly sending backspaces into whatever has focus — one desync and your document is mangled. Typed text should be final.
  2. Per-pause typingsegmentation = "vad". Speak; roughly half a second after each natural pause, that utterance is typed. This is the closest voxtype comes to a streaming feel: text flows in sentence-sized pieces while you keep talking. Trade-off: the model transcribes each fragment with only that fragment’s context, so accuracy is a notch lower.
  3. Whole-takesegmentation = "hold". Nothing appears while you speak (the ghost indicator is your feedback); on toggle-off the entire take is transcribed as one segment and typed in one go. Maximum accuracy — the model sees full sentence context — and most apps undo it as a single edit (keystrokes are synthesized, so undo grouping is up to the focused app). Requires toggle mode, since the wake word can only be heard by continuous per-utterance transcription.

Wake and vad modes always use per-pause typing (2); toggle mode lets you pick between (2) and (3), and defaults to (3), whole-take, with a parakeet engine — so out of the box you get maximum-accuracy push-to-talk. Set segmentation = "vad" if you’d rather see text appear as you pause.

Push-to-talk dictation (the default, and the recommended daily driver). No wake word involved at all; maximum accuracy; text lands in one go (a single edit to undo, in most apps). This is exactly what you get out of the box — no config needed — since mode defaults to toggle, the engine is auto-selected (a parakeet engine), and segmentation then defaults to hold. Spelled out, that is:

mode = "toggle"
segmentation = "hold"
# engine is auto-selected: parakeet-mlx on Apple Silicon,
# parakeet on Intel — you normally leave it unset

Toggle with live feedback. Same hotkey workflow, but text appears at every pause instead of at the end — useful when you want to see progress while dictating something long, at some cost in accuracy:

mode = "toggle"
segmentation = "vad"

Hands-free with a wake word. Say “hey claude …” to dictate, “stop listening” (or silence) to re-arm; the hotkey still toggles manually. Per-pause typing is inherent to this mode:

mode = "wake"
wake_word_aliases = ["hey cloud"] # add what the model mishears

Always-on transcription. Types everything it hears while running — for captioning yourself or short bursts of use:

mode = "vad"

(These recipes leave engine unset so it auto-selects for your machine; set it explicitly only to force a specific engine.)

Selected with engine / --engine. All run 100% on-device.

EngineRuns onSpeed*Notes
parakeet-mlxApple GPU (MLX)~40x realtimeDefault on Apple Silicon. fp16 Parakeet-TDT v3: best accuracy and speed. Weights from HuggingFace on first run.
parakeetCPU (sherpa-onnx)~32x realtimeDefault on other machines. int8 Parakeet-TDT v3 (or fp16 v2 via parakeet_model); ~490 MB download.
moonshineCPU (ONNX)streamingMoonshine streaming models; smallest footprint. Opt-in: uv tool install "voxtype[moonshine]" (no Intel-macOS build).

Both parakeet engines ship with the base install; the default is chosen for your machine, so most people never set engine at all.

*measured on an M-series Mac; see parakeet_threads for CPU tuning.

# ~/.config/voxtype/config.toml — all keys optional; the values shown
# are the defaults (except `engine`, which is auto-selected per machine)
# Activation: "toggle" (hotkey), "vad" (hands-free), "wake" (wake word)
mode = "toggle"
# Engine: "parakeet-mlx" | "parakeet" | "moonshine". Auto-selected when
# unset: parakeet-mlx on Apple Silicon, parakeet on Intel. Set it only to
# force a choice; the value below is just the Apple-Silicon case.
engine = "parakeet-mlx"
# "vad" types each utterance when you pause; "hold" records everything
# between toggle-on/off and transcribes the whole take at once (parakeet
# engines + toggle mode only). Default: "hold" with a parakeet engine in
# toggle mode (the common case), otherwise "vad".
segmentation = "hold"
# parakeet (CPU) build: "v3-int8" | "v2-fp16"; and decode threads
parakeet_model = "v3-int8"
parakeet_threads = 4
# parakeet-mlx model (HuggingFace id)
mlx_model = "mlx-community/parakeet-tdt-0.6b-v3"
# moonshine model: tiny | base | tiny-streaming | base-streaming |
# small-streaming | medium-streaming
model_arch = "medium-streaming"
language = "en"
# Hotkeys (pynput or bracket-less syntax; `voxtype hotkey` records one)
hotkey = "<ctrl>+;" # toggle recording
# A second toggle for the laptop keyboard (macOS): tap a modifier key
# twice on its own. One of left_alt right_alt left_cmd right_cmd
# left_ctrl right_ctrl left_shift right_shift ("alt" = Option). The key
# keeps working as a normal modifier. "" disables.
double_tap_key = ""
double_tap_ms = 400 # max gap between the two taps, press to press
cancel_hotkey = "<esc>" # cancel recording (only intercepted WHILE recording)
paste_hotkey = "" # re-type last transcript, e.g. "<cmd>+<ctrl>+v"
# Wake mode
wake_word = "claude"
wake_word_aliases = [] # misspellings the model produces, e.g. ["hey cloud"]
stop_phrase = "stop listening"
idle_timeout = 20.0 # seconds of silence before wake mode re-arms
# Spoken submit: saying one of these as an ENTIRE utterance presses Enter
submit_phrases = ["over", "go", "submit"]
# Transcript cleanup: strip standalone fillers (uh, um, ...) and
# collapse 3+ word stutters ("I I I think" -> "I think")
strip_fillers = true
trailing_space = true # append a space after each typed utterance
# Toggle chimes. sounds = false silences the start/stop chime entirely
# (or run with --no-sounds). Names are system sounds
# (/System/Library/Sounds) or file paths.
sounds = true # false = no chime when recording toggles on/off
sound_start = "Glass"
sound_stop = "Bottle"
# Keep each session's text on the clipboard too
copy_to_clipboard = false
# Floating ghost indicator while recording (macOS): a little blue
# ghost whose mouth opens with your voice.
overlay = true
overlay_flex = 1.0 # how much the face flexes its shape (higher = more)
overlay_speed = 1.0 # animation speed (lower = slower/gentler)
overlay_opacity = 1.0 # 0.1–1.0; lower it if the ghost hides text under it
# Keep the model's memory warm (parakeet-mlx only). After this many
# minutes without a decode, voxtype quietly decodes a short silent
# clip so the idle model stays recently-used and macOS is far less
# likely to evict it to swap — otherwise, on a memory-pressured
# machine, the first take after a long pause can stall for seconds
# paging the model back in. Keeps ~1.7 GB in active use. 0 disables;
# max 1440 (a day). See the note below on the one trade-off.
keepalive_minutes = 0.0

Turn this on if your Mac runs under heavy memory pressure and your first take after a pause is sometimes slow — several seconds for a few seconds of audio, when a normal take is near-instant. That slowness is macOS having evicted the idle model (~1.7 GB) to swap; the periodic silent decode keeps those pages in active use so it is far less likely to happen. A value of 5 (minutes) is a reasonable start. On a machine with memory to spare, leave it off — it is not free, it keeps ~1.7 GB resident.

One trade-off worth knowing:

  • The keepalive decode runs on the same thread that reads the microphone, so while it runs, capture pauses. It skips itself during a take, during an utterance, and for 30 seconds after any hotkey press, so it should never collide with you speaking — but if you happen to press the hotkey in the instant it starts, the first fraction of a second of your dictation can be lost.
  • In practice that window is ~0.2 s, because a keepalive on a warm model is fast, and keeping the model warm is the whole point. A multi-second keepalive means the model had already been evicted, which is the situation this option prevents.
voxtype [flags] run with config + flag overrides
voxtype setup [--config PATH] [--force] interactive walkthrough -> writes config
voxtype init [--config PATH] [--force] write the commented sample config to edit
voxtype hotkey press a chord; prints the config line
voxtype skill install the voxtype skill into Claude + Codex
voxtype --help full flag reference (per-subcommand: e.g. voxtype setup --help)

Flags mirror the config keys: --mode, --engine, --segmentation, --parakeet-model, --model-arch, --language, --hotkey, --wake-word, --stop-phrase, --no-sounds, --no-overlay, --config PATH.

double_tap_key adds a second way to start and stop recording, next to the hotkey chord: tap one modifier key twice, by itself. It exists for the laptop keyboard, where a chord like Ctrl+; is awkward without an external keyboard; right_alt (the right Option key) is a good choice because nothing else uses it alone.

  • Both triggers stay active at once; use whichever is under your hand.
  • The taps must be clean: press, release, press, release, with no other key in between and within double_tap_ms of each other (press to press). Holding the key to type an Option-shortcut or an accented character never triggers it.
  • The modifier is never swallowed — voxtype only observes it — so Option, Command, and friends keep working everywhere.
  • macOS only (it rides on the same event tap as the chord).

Both spellings work everywhere a chord is accepted:

hotkey = "<ctrl>+;" # pynput style
hotkey = "ctrl+;" # bracket-less
hotkey = "cmd+shift+f5" # named keys too

Easiest of all: run voxtype hotkey, press the combo you want, and paste the printed line into your config. On macOS matched chords are fully suppressed — the focused app never sees them — and context-dependent keys like Esc are only intercepted while recording.

Grant these to your terminal app (System Settings → Privacy & Security), once each:

  • Microphone — to hear you
  • Accessibility — to type into other apps
  • Input Monitoring — for the global hotkeys
  • Every utterance’s fate is logged to the terminal (typed: ..., heard (awaiting wake word): ..., dropped, decoded to empty text) — nothing is discarded silently. Read these lines first.
  • Wake word not firing? Check the heard lines for how the model actually spelled it and add that to wake_word_aliases; prefer a two-word phrase (“hey claude”) over a bare word.
  • Quiet dynamic mic (Shure MV7 class)? Automatic gain control is built in; if speech still isn’t detected, move closer to the mic.
  • take was silent (...): microphone muted, held by another app, or its stream went stale — reopening the microphone? voxtype measured no signal at all during that take (a dead mic reads about a millionth of full scale; even a quiet room reads a thousand times more). Two known causes: a meeting app (Zoom) left the mic muted at the system level — unmute there, or tap the mic’s own mute button — or the audio stream went stale after the device setup changed (opening the lid, plugging in a mic). voxtype reopens the stream on its own, so the stale case fixes itself: just dictate again. Hold mode only; in wake/vad mode a dead mic simply never hears anything.
  • Dictated into the wrong window? Set paste_hotkey and re-type the last session anywhere.