A narrator for macOS. Select an article, an email, a PDF, a code comment, anything. Press a shortcut. Apollo reads it to you in a natural voice while you keep working. Sits quietly in your menu bar until you need it.
Runs entirely on-device on Apple Silicon using MLX + Qwen3-TTS. 10 languages, 9 voices, no cloud, no API keys.
There's a CLI too: apollo "narrate this".
iPhone has had a good narrator for years. macOS still ships the 2015-era Alex/Samantha voices: robotic, monotone, painful past a sentence or two. Apollo runs a current neural model (Qwen3-TTS) on your Mac's GPU instead. Same on-device privacy, much better audio.
Things people use it for: reading long articles, catching typos by hearing writing read back, practicing pronunciation in other languages, listening to PDFs or research while cooking or walking.
- Apple Silicon Mac (M1 or newer)
- macOS 14 or newer
- Xcode installed
- Around 3 GB free disk
git clone <this-repo>
cd Apollo
# One-time. Xcode 26 needs you to download the Metal toolchain yourself.
xcodebuild -downloadComponent MetalToolchain
# Build the GUI app and the CLI.
xcodebuild -scheme Apollo -configuration Release -derivedDataPath build -destination 'platform=macOS' build
xcodebuild -scheme ApolloCLI -configuration Release -derivedDataPath build -destination 'platform=macOS' build
# Wrap the binary into Apollo.app and install it.
./bundle-apollo.sh --release
./install.sh --releaseThat puts Apollo.app in /Applications and an apollo command in ~/.local/bin. First time you use it, it downloads the model (about 600 MB) and caches it forever.
A note on signing. I don't have an Apple Developer Program account, so Apollo is ad-hoc signed. On your own machine this is fine, you compiled it, macOS trusts it. If you copy Apollo.app to someone else's Mac, Gatekeeper will warn them. They can right-click Apollo.app, choose Open, and then Open again in the dialog. Or run xattr -dr com.apple.quarantine /Applications/Apollo.app.
If you want to skip the GUI install and just get the CLI:
./install.sh --release --no-cli # only the .app
./install.sh --user # ~/Applications, no /Applications write neededClick the 🎭 in the top-right corner. The panel has buttons for narrating your clipboard, narrating a sample phrase, or stopping mid-sentence, plus pickers for language and voice, and sliders to tune how the model sounds.
This is the part you'll actually use day to day. After installing, open System Settings → Keyboard → Keyboard Shortcuts → Services → Text. Find "Speak with Apollo" and assign a shortcut. I use ⌥+S.
Then in any app (Safari, Notes, Mail, Pages, a PDF, even your own terminal), highlight some text and press your shortcut. Apollo narrates it. Switch apps, keep typing, the audio keeps going. Hit your shortcut on something new to interrupt and start narrating that instead.
You can also right-click your selection and pick Services > Speak with Apollo.
apollo "Hello, world."
apollo --speaker Ono_Anna --language Japanese "こんにちは"
apollo --output greeting.wav "save this to a file"
echo "pipe me" | apollo
apollo --speakers
apollo --languages
apollo --help| Speaker | Sounds like | Best for |
|---|---|---|
| Ryan | Dynamic male, energetic | English |
| Aiden | Sunny American male | English |
| Vivian | Bright young female | Chinese |
| Serena | Warm gentle female | Chinese |
| Uncle_Fu | Older male, mellow | Chinese |
| Dylan | Young male, Beijing | Chinese |
| Eric | Lively male, Sichuan | Chinese |
| Ono_Anna | Playful female | Japanese |
| Sohee | Warm female | Korean |
Any speaker can speak any of the 10 supported languages. They sound best in their native one. Apollo's voice picker shows a "native" badge to nudge you toward good pairings.
Supported languages: English, Chinese, Japanese, Korean, French, German, Spanish, Italian, Portuguese, Russian.
"MLX error: Failed to load the default metallib". You ran the CLI binary directly instead of via the wrapper, or you forgot ./bundle-apollo.sh. The Metal kernels live inside Apollo.app. The CLI is a shell wrapper that exec's into the .app. Reinstall with ./install.sh --release.
"Speak with Apollo" isn't in the Services menu. Quit and reopen the app you're using (Services list is cached per-app at launch). If still missing, enable the checkbox in System Settings, Keyboard, Services, Text.
Gatekeeper says "Apple cannot verify Apollo". Right-click Apollo.app in Finder, choose Open, then Open again in the dialog. Only needed once.
apollo not found. ~/.local/bin isn't on your PATH. Add export PATH="$HOME/.local/bin:$PATH" to ~/.zshrc, or reinstall with --system to use /usr/local/bin.
Speech sounds garbled. Sampling parameters drifted. Hit Reset defaults in the panel footer.
Apollo writes to ~/Library/Logs/Apollo/Apollo.log. Tail it if something is misbehaving:
tail -f ~/Library/Logs/Apollo/Apollo.logIt also logs through os.Logger, so you can filter Console.app by subsystem com.local.apollo.narrator.
There's one model: mlx-community/Qwen3-TTS-12Hz-0.6B-CustomVoice-8bit (about 600 MB, 8-bit quantized). Apollo loads it once, keeps it in RAM, and serves both the menu bar app and the CLI from a singleton SpeechEngine. Text is chunked on sentence boundaries, each chunk goes to the model, the resulting PCM samples are pushed into an AVAudioPlayerNode queue. Generation of chunk N+1 overlaps with playback of chunk N.
When you connect AirPods mid-speech, the engine catches the configuration-change notification, tears down the audio graph, and re-schedules unplayed buffers on the new device.
Settings (voice, language, sampling parameters) live in UserDefaults so they survive restarts.
For iteration, build Debug and run via the helper:
xcodebuild -scheme Apollo -configuration Debug -derivedDataPath build -destination 'platform=macOS' build
./apollo-run --debugapollo-run sets DYLD_FRAMEWORK_PATH so the Metal kernels are found without going through the install flow. Debug builds are noticeably slower at inference than Release. Fine for UI work, not for measuring quality.
Sources/Apollo/ GUI app
ApolloApp.swift SwiftUI panel + design tokens
AppLog.swift File logger
ServiceProvider.swift macOS Services entry point
Settings.swift @Observable settings, UserDefaults-backed
Speak.swift SpeechEngine: MLX + AVAudioEngine
Sources/ApolloCLI/main.swift Command-line tool
Tools/make-icon.swift Icon generator
Info.plist App bundle metadata + Services declaration
bundle-apollo.sh Wraps build output into Apollo.app
install.sh Installs .app + CLI wrapper
apollo-run Dev launcher (Debug builds)
Apollo is a thin wrapper around hard work by other people:
- Qwen3-TTS is the actual TTS model (Alibaba, Apache 2.0)
- mlx-audio-swift provides the Swift bindings for MLX TTS models
- mlx-swift is Apple's MLX framework
- swift-transformers handles tokenizers and the Hugging Face client
I built the menu-bar UI, the CLI, the install scripts, and the audio pipeline glue. Everything that's hard is upstream.