Local, hotkey-driven text-to-speech for macOS. Highlight any text, press Cmd+I, and Kokoro reads it in a voice that does not sound like a 2008 GPS unit.
- Runs entirely on your machine. No API calls, no cloud, no telemetry.
- 50+ voices across English (US/UK), Spanish, French, Hindi, Italian, Japanese, Portuguese (BR), and Mandarin.
- Menubar UI to switch voices and speed without touching code.
- Auto-starts at login via
launchd. The model stays loaded so the hotkey is instant.
macOS has built-in say. The voices are flat, robotic, and unpleasant for anything longer than a sentence. Kokoro is a small (~340MB) neural TTS model with voices that are genuinely listenable. This wraps it as a localhost server that a Hammerspoon hotkey can hit.
- macOS (Apple Silicon or Intel)
- Homebrew
- uv (
brew install uv) - ~400MB of disk for the model files
- Hammerspoon (the installer will install it for you if missing)
git clone https://github.com/<you>/kokoro-hotkey.git
cd kokoro-hotkey
./install.shThe installer will:
- Install Hammerspoon (if missing).
- Copy the server to
~/.local/tts/anduv syncits Python deps. - Download Kokoro v1.0 model files into
~/.local/tts/models/. - Install a
launchdagent at~/Library/LaunchAgents/local.kokoro-hotkey.plistand load it. - Drop a Hammerspoon module at
~/.hammerspoon/tts.luaand addrequire("tts")to yourinit.lua.
After it finishes, grant Hammerspoon Accessibility permission once:
System Settings, Privacy & Security, Accessibility, toggle Hammerspoon ON.
Then click the Hammerspoon menubar icon and choose Reload Config.
| Hotkey | Action |
|---|---|
Cmd+I |
Speak the current selection |
Cmd+Shift+I |
Stop playback |
Click the TTS menubar item for:
- Voice picker (grouped by language and gender, picking a voice plays a sample)
- Speed picker (0.7x to 2.0x)
- Test current voice
- Stop, restart server, open log
Settings persist to ~/.local/tts/config.json.
The server listens on 127.0.0.1:8765.
# speak something
curl -X POST http://127.0.0.1:8765/speak \
-H 'Content-Type: application/json' \
-d '{"text":"hello world"}'
# stop
curl -X POST http://127.0.0.1:8765/stop
# list voices
curl http://127.0.0.1:8765/voices
# get / set defaults
curl http://127.0.0.1:8765/config
curl -X POST http://127.0.0.1:8765/config \
-H 'Content-Type: application/json' \
-d '{"voice":"am_michael","speed":1.1}'Voice IDs follow Kokoro's convention: <lang><gender>_<name>.
aAmerican English,bBritish EnglisheSpanish,fFrench,hHindi,iItalian,jJapanese,pPortuguese (BR),zMandarinffemale,mmale
Some commonly recommended voices:
af_heart(default),af_bella,af_nicole,af_skyam_michael,am_puck,am_fenrirbf_emma,bf_isabellabm_george,bm_lewis
Pick by clicking through the menubar to audition them.
[ Hammerspoon ] -- Cmd+I --> simulate Cmd+C, read pasteboard
|
| POST /speak {"text": "..."}
v
[ Flask server (~/.local/tts/server.py) ]
|
| kokoro_onnx synth -> /tmp/tts-<uuid>.wav
v
[ afplay subprocess ] <-- killable via /stop
The Flask server is single-process, in-memory model. Generation is fast enough on M-series chips that streaming chunks isn't necessary for the typical "highlight a paragraph" use case.
Cmd+I does nothing. Hammerspoon doesn't have Accessibility permission. Grant it in System Settings.
Cmd+I plays the previous clipboard, not the selection. The app you're in didn't put the selection on the pasteboard within 180ms of Cmd+C. Increase the wait in ~/.hammerspoon/tts.lua (hs.timer.usleep(180000)).
TTS error 0 / connection refused. The server isn't running. Check ~/.local/tts/server.log, then launchctl kickstart -k gui/$(id -u)/local.kokoro-hotkey.
No "TTS" item in the menubar. Hammerspoon hasn't reloaded. Click its menubar icon, "Reload Config".
Voices submenu is empty. The Lua module loaded before the server was ready. Reload Hammerspoon.
./uninstall.shStops and removes the LaunchAgent, removes the Hammerspoon module and the require("tts") line from your init.lua, and asks before deleting ~/.local/tts/ (which holds the 340MB model files).
- Kokoro by hexgrad, the underlying TTS model.
- kokoro-onnx by thewh1teagle, the ONNX runtime wrapper.
- Hammerspoon for the hotkey and menubar plumbing.
MIT. See LICENSE.