On-device text-to-speech for macOS. Copy text anywhere, press a hotkey, and a local Kokoro voice reads it aloud. Everything runs on the machine (Apple Silicon). No cloud, no API keys, no account.
Reednow is a menu bar app. It drives a local Python TTS engine as a warm background process, so after the first read every press is near-instant.
Requires macOS 14+ on Apple Silicon.
Needs Xcode's Swift toolchain and uv.
git clone https://github.com/almostonpurpose/reednow cd reednow uv tool install --editable . # installs the reednow engine + CLI cd app ./build.sh # -> Reednow.app (dev build, drives the installed engine) open Reednow.app
package.sh embeds a relocatable Python, all dependencies, and the model inside
the app, then produces a drag-to-Applications DMG that needs nothing installed:
cd app ./package.sh # -> ~/Downloads/Reednow.dmg (~780 MB)
The DMG is ad-hoc signed, not notarized. A recipient opens it, drags Reednow to
Applications, then right-clicks the app and chooses Open once (macOS quarantines
apps downloaded from the internet). Notarization requires an Apple Developer
account and adds a notarytool + stapler step to package.sh.
- Click the menu bar icon and pick a voice and speed.
- Open Settings and record a global hotkey.
- Copy text anywhere, press the hotkey. Press it again to stop.
The icon animates while the engine generates and speaks. The first read after launch takes a few seconds while the model loads; every read after is fast.
The engine is also a standalone command:
reednow "Hello, this is a test." # speak text reednow -f article.txt # read a file (markdown is stripped) reednow -c # read the clipboard pbpaste | reednow # read piped input reednow -v am_michael -s 1.0 "..." # pick a voice and speed reednow -o out.wav "..." # write a wav instead of playing reednow --list-voices
Other formats go through an extractor:
| Format | Command |
|---|---|
pdftotext file.pdf - | reednow |
|
| Web | curl -s URL | <readability tool> | reednow |
text -> clean/chunk -> Kokoro (mlx-audio) -> afplay
(file/clipboard/ (streaming: the next chunk
stdin/argument) synthesizes while the current one plays)
reednow/engine.py— TTS engine and voice config.reednow/text.py— markdown cleanup and sentence-aware chunking.reednow/cli.py— input sources and streaming playback for the CLI.reednow/server.py— warm daemon (--serve): keeps the model resident and speaks a JSON-line protocol over stdin/stdout.app/— SwiftUI menu bar app (SwiftPM, no Xcode project). Drives the daemon and owns the UI, hotkey, and clipboard handling.
Run the daemon protocol test with python tests/test_daemon.py.
MIT. The Kokoro model is licensed separately (Apache-2.0).