Push-to-talk voice dictation for macOS. Hold ⌘⌥, speak, release — text streams to your cursor.
Project description
LocalFlow
Push-to-talk, on your Mac. Hold a hotkey, speak, release — text streams to your cursor.
LocalFlow is a lightweight macOS menubar app that transcribes your voice locally. No cloud, no API keys, no subscriptions, no data leaving your machine — just fast, private dictation that works in any app.
Why LocalFlow
Most dictation tools either require a cloud subscription, only work inside a specific app, or send your audio to a remote server. LocalFlow runs entirely on-device, giving you:
- Privacy — audio never leaves your Mac
- Speed — streaming transcription starts appearing within ~300ms of releasing the key on M1
- Simplicity — one hotkey, works everywhere, no setup beyond install
Requirements
- macOS 13+, Intel or Apple Silicon
- Python 3.10–3.13 (Python 3.14 is not yet supported — pre-built wheels for some dependencies are unavailable)
- Homebrew
Installation
brew install portaudio
pip install localflow
That's it. LocalFlow detects your hardware and installs the right backend automatically:
| Mac | Backend | Notes |
|---|---|---|
| Apple Silicon (M1/M2/M3/M4) | mlx-whisper | Fastest — runs natively via MLX |
| Intel | faster-whisper | CPU-optimized via CTranslate2 |
Permissions
LocalFlow needs three macOS permissions. Go to System Settings → Privacy & Security and grant:
| Permission | Why |
|---|---|
| Microphone | To capture your voice |
| Accessibility | To paste transcribed text |
| Input Monitoring ⚠️ | To detect the global ⌘⌥ hotkey |
Input Monitoring is the most commonly missed permission. Without it, the hotkey silently does nothing. Add your terminal app (Terminal.app, iTerm2, etc.) under System Settings → Privacy & Security → Input Monitoring.
Usage
1. Launch the app
localflow
A microphone icon appears in your menubar.
2. Enable dictation
Click the menubar icon → flip the toggle ON.
3. Dictate anywhere
Hold ⌘ Command + ⌥ Option in any app, speak, then release. Text streams to your cursor as transcription progresses.
The toggle is OFF by default so the microphone is never opened until you choose to enable it.
Models
LocalFlow uses quantized Whisper models from Hugging Face. The model is downloaded on first use (~150MB for small) and cached locally — no network needed after that.
localflow # default: small
localflow --model medium # more accurate, slightly slower
localflow --model large # best accuracy
localflow --list-models # show all options
| Model | Speed (M1) | Accuracy |
|---|---|---|
| tiny | ~100ms | Basic |
| base | ~200ms | Decent |
| small | ~300ms | Good (default) |
| medium | ~800ms | Better |
| large | ~2–3s | Best |
You can also set the model via environment variable:
LOCALFLOW_MODEL=large localflow
How it works
- Global hotkey — macOS
NSEventmonitors for ⌘⌥ held simultaneously, across all apps - Audio capture — sounddevice records mic input at 16kHz mono
- Streaming transcription — faster-whisper yields segments as it processes, so text starts appearing before the full audio is transcribed; mlx-whisper on Apple Silicon transcribes the whole clip in one fast batch (~300ms)
- Text injection — each segment is copied to clipboard and pasted via
osascript(⌘V simulation)
All processing is local. No audio is stored permanently — the temp WAV file is discarded after transcription.
Troubleshooting
Hotkey does nothing → Check Input Monitoring permission. This is almost always the cause.
No text appears after speaking → Check Accessibility permission so the app can simulate ⌘V.
Transcription is slow on first use → The model is being downloaded. Subsequent runs use the cached model.
App doesn't appear in Dock → That's intentional — LocalFlow lives in the menubar only.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file localflow-0.1.6.tar.gz.
File metadata
- Download URL: localflow-0.1.6.tar.gz
- Upload date:
- Size: 10.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2bb15b415ea978f71ef42b5c2f40e966ff92db02827d1bd76678a3a49d606696
|
|
| MD5 |
61a2d42c9590e8d8d7974ddd6f35c69b
|
|
| BLAKE2b-256 |
288ff0dbd4f08302ed38be0b58e5f416353f47bc2047c24cc3d5c7bbe381b2e6
|
File details
Details for the file localflow-0.1.6-py3-none-any.whl.
File metadata
- Download URL: localflow-0.1.6-py3-none-any.whl
- Upload date:
- Size: 10.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5bff2fec655ed71e52be99cf25e1edef528c603b72fe0df6daa5641c29c2d82a
|
|
| MD5 |
ae3a43ab69b7bc56ad240148ff4f5f9d
|
|
| BLAKE2b-256 |
7be149dc87ff2cfc26f5e2d93261b5a1f4e20f69a3a6ca509f81a99ec7c4c7f0
|