Skip to content

cris-m/Apollo

Repository files navigation

Apollo

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".

Why this exists

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.

What you need

  • Apple Silicon Mac (M1 or newer)
  • macOS 14 or newer
  • Xcode installed
  • Around 3 GB free disk

Install

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 --release

That 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 needed

Use it

From the menu bar

Click 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.

From any app

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.

From the terminal

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

Voices

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.

When something breaks

"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.

Logs

Apollo writes to ~/Library/Logs/Apollo/Apollo.log. Tail it if something is misbehaving:

tail -f ~/Library/Logs/Apollo/Apollo.log

It also logs through os.Logger, so you can filter Console.app by subsystem com.local.apollo.narrator.

How it works

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.

Building during development

For iteration, build Debug and run via the helper:

xcodebuild -scheme Apollo -configuration Debug -derivedDataPath build -destination 'platform=macOS' build
./apollo-run --debug

apollo-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.

Files

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)

Credits

Apollo is a thin wrapper around hard work by other people:

I built the menu-bar UI, the CLI, the install scripts, and the audio pipeline glue. Everything that's hard is upstream.

About

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.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors