Read selected text aloud on any webpage. This is a thin UI layer that defers to the Out Loud desktop app over localhost:51730 — everything stays on your machine.
For the big-picture architecture, see the root README.
- Install
- Use
- Auto-start the desktop app on login (macOS)
- Verify the API
- Troubleshooting
- Repository layout
- Related docs
- License
- Install the Out Loud desktop app — see root README → Install.
- Load the extension in Chrome:
- Open
chrome://extensions/ - Enable Developer mode (top right)
- Click Load unpacked and select this
chrome-extension/folder
- Open
The extension auto-connects to the desktop app as long as it's running.
- Select text on any webpage.
- Click the Out Loud extension icon to open the side panel.
- Pick a voice and language.
- Click play.
If you'd rather not launch the app manually every time, register a launch agent:
cat > ~/Library/LaunchAgents/com.outloud.server.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.outloud.server</string>
<key>ProgramArguments</key>
<array>
<string>/Applications/Out Loud.app/Contents/MacOS/Out Loud</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/outloud.log</string>
<key>StandardErrorPath</key>
<string>/tmp/outloud.err</string>
</dict>
</plist>
EOF
launchctl load ~/Library/LaunchAgents/com.outloud.server.plistManage it:
launchctl start com.outloud.server
launchctl stop com.outloud.server
launchctl unload ~/Library/LaunchAgents/com.outloud.server.plist # uninstall
tail -f /tmp/outloud.logcurl -s http://127.0.0.1:51730/api/v1/audio/voices | head -c 200If you get JSON back, the extension will find the server. For the full API, see ../docs/app/api.md.
The desktop app isn't running, or isn't on port 51730. Launch Out Loud, then reopen the side panel.
Refresh the webpage after installing the extension — content scripts don't inject into already-open tabs.
lsof -i :51730chrome-extension/
├── manifest.json Extension config (Manifest V3)
├── background.js Service worker
├── content.js Text selection detection
├── sidepanel.{html,js} Side-panel UI
├── options.{html,js} Options page
├── src/ TTS engine, streaming player, utilities
└── icons/ Extension icons
../docs/extensions/testing.md— end-to-end testing../docs/app/api.md— HTTP API reference../safari-extension/README.md— same codebase, Safari port