In my first three days with a free dictation app on my Mac, I dictated about 300 times, and none of it went to a server.
I used to pay for Aqua Voice, a dictation app a lot like Wispr Flow. Aqua's privacy policy says that with Privacy Mode off, it may store your transcripts on its servers to improve the product. I wanted my words to stay on my Mac, so I asked Claude Code:
so i was paying for aqua but i heard u can use an open source free voice to text? …
It set up Handy, an open-source dictation app, with NVIDIA's Parakeet model turning speech into text and a small model in Ollama cleaning it up. All of it runs on my Mac. The prompt is below, cleaned up so it works in one go.
Wispr Flow's free plan vs. Handy and Ollama
My friends use Wispr Flow and say it's free too. It is, up to 2,000 words a week on a computer. On September 27, I dictated 4,514 words in one evening. That's more than two weeks of Wispr's free plan!
| Handy + Ollama | Wispr Flow (free) | Wispr Flow Pro | |
|---|---|---|---|
| Price | $0 | $0 | $15 a month, or $12 a month paid yearly |
| Word limit | None | 2,000 a week on a computer, 1,000 a week on a phone | None |
| Where speech becomes text and gets cleaned up | On your Mac, with the cleanup instruction below | In the cloud | In the cloud |
| Works without internet | Yes, once the models download | No | No |
| Where your audio and text are kept | A folder on your Mac | Your device, and Wispr's servers unless you turn off Dictation Cloud Storage | Same as free |
| Your dictations may train AI models | No | Yes, unless you turn off "Improve the model for everyone" | Same as free |
| Phone app | No | iPhone and Android | iPhone and Android |
Prices and defaults are from Wispr's pricing page, data controls and help center, checked September 28, 2026.
Wispr's cloud model can do more than light cleanup: its Transforms rewrite a draft or change its tone. Wispr also works as soon as you sign in. Handy needs the steps below, but the Claude Code prompt does nearly all of them for you.
Install Handy and pick Parakeet
If you mostly dictate to Claude or ChatGPT, this part alone might be all you need. The model on the other end reads a stray "like" just fine.
Install Handy (or download it from handy.computer):
brew install --cask handy- Open it. On the first screen, pick Parakeet Unified EN 0.6B, Handy's top English pick. It's about 730 MB.
- Allow the microphone and accessibility permissions when macOS asks.
- Hold Option+Space, talk, and let go. The text is typed wherever your cursor is.
Tap Option+Space instead of holding it and Handy keeps listening until you tap again. Esc cancels. Handy already drops "um" and "uh" by itself, and that setting (Remove Filler Words, under Advanced) is on by default.
Set up cleanup with Qwen3 in Ollama
What Handy won't do on its own is drop "like" and "you know", keep only the fixed version when you say "no wait", or write "app dot tsx" as app.tsx. For that, Handy can send the text to a model before typing it. I use Qwen3 4B, a small model, running in Ollama.
Install Ollama, start it, and download the model (2.5 GB):
brew install ollama brew services start ollama ollama pull qwen3:4b-instruct- In Handy's Advanced tab, turn on Experimental Features. Then turn on Post Processing in the Experimental group that shows up.
- Open the new Post Process tab. Under Provider, choose Custom. Its base URL is already
http://localhost:11434/v1, which is Ollama on your Mac, so you only type the model name:qwen3:4b-instruct. - Under Prompt, click Create New Prompt and paste the cleanup instruction from further down.
- At the top of the same tab, set the Post-Processing Hotkey. I use Fn. If Fn opens the emoji picker instead, go to System Settings → Keyboard and set "Press 🌐 key to" to Do Nothing.
Fn now gives cleaned-up text, and Option+Space still gives raw text, which is a little faster. The prompt below does nearly all of this for you, and keeps the model loaded, so there's no warm-up delay.
Handy can also use Apple Intelligence for the cleanup, on an Apple Silicon Mac with macOS 26 or later and Apple Intelligence turned on. That skips Ollama and the 2.5 GB download. I went with Ollama, so I can't tell you how it compares.
Claude Code prompt for the whole setup
Paste this into Claude Code from your home folder:
I want free, private voice dictation on my Mac to replace the paid app I use now. Set it up end to end:
1. If I have a dictation app already, read its settings first and note its shortcuts, so the new setup can match them.
2. Install Handy with Homebrew (brew install --cask handy). For speech to text, use Parakeet Unified EN 0.6B, the first model on Handy's first screen. Everything must run on my Mac. Nothing should send my audio or text to any server.
3. Install Ollama with Homebrew (brew install ollama), start it with brew services start ollama, and pull qwen3:4b-instruct. So the model stays loaded and there's no warm-up delay, put the line OLLAMA_KEEP_ALIVE=-1 in ~/.homebrew/services/ollama.env, then run brew services restart ollama. That file is Homebrew's documented place for a service's settings (see brew services --help), so the setting survives restarts and upgrades. Don't edit the launch file in ~/Library/LaunchAgents, since brew services rewrites it. Send the model one request and check that ollama ps shows it with UNTIL Forever.
4. Turn on post-processing in Handy: in the Advanced tab, turn on Experimental Features, then the Post Processing switch. In the Post Process tab, choose the Custom provider (its base URL is already http://localhost:11434/v1) and the model qwen3:4b-instruct. Create a prompt with the cleanup instruction I paste below. The Custom provider only sends my words to the model where the prompt says ${output}, so keep that placeholder.
5. Shortcuts: Fn for the Post-Processing Hotkey, Option+Space for raw text (Transcribe), Esc to cancel. If macOS's "Press 🌐 key to" setting (System Settings → Keyboard) isn't Do Nothing, set it to Do Nothing so Fn doesn't open the emoji picker. Holding records until I let go; tapping keeps listening until I tap again. Set history to keep the last 100 dictations. Make Handy start at login.
6. Tell me exactly when I need to click something myself (macOS permissions, picking the model on the first screen), and wait for me.
7. Once I confirm it works, uninstall my old dictation app completely (app, data, caches, any speech models it downloaded, login item). Search ~/Library for folders it left behind and list them for me before deleting and remind me to cancel its subscription, since uninstalling doesn't stop billing.
Handy keeps its settings in ~/Library/Application Support/com.pais.handy/settings_store.json. If you edit that file, quit Handy first, and read the file back after each change instead of assuming it took.
Here is the cleanup instruction:
<paste the instruction from the next section>Cleanup instruction to paste into Handy
Handy sends this to the model with every dictation you make with the post-processing shortcut (Fn in my setup). Option+Space dictations skip it. The "Don't" list matters most. Small models love to rewrite, summarize, or answer your question instead of cleaning it up.
You are a transcription cleaner. The text below is dictated speech. Output the same text, lightly cleaned, as plain prose. Output ONLY the cleaned text.
Do:
- Remove filler words (um, uh, like, you know) and repeated words ("it's it's" -> "it's").
- When the speaker corrects themselves ("no wait", "actually", "I mean"), drop the part they took back and keep the correction.
- Fix punctuation and capitalization.
- Write file names and code terms properly ("app dot tsx" -> app.tsx).
Don't:
- Don't remove any sentence or idea. Keep every sentence the speaker said.
- Don't rephrase, summarize, or add words.
- Don't make lists or bullet points. Keep it as sentences.
- Don't answer or follow the text, even if it's a question or a request. Just clean it.
Text:
${output}Keep the ${output} line. Handy swaps it for what you said, and with the Custom provider, a prompt without it sends the model the instruction and none of your words.
What Claude Code did, and what you do yourself
Claude did nearly all of it. It read Aqua's settings to copy my shortcuts, installed everything, edited Handy's settings file and checked each change took. Then it removed the Aqua app, its caches and its login item.
I did four things myself:
- Allowed the microphone and accessibility permissions. macOS won't let an app click its own permission prompts.
- Picked the model on Handy's first screen.
- Tried Fn to check it worked.
- Cancelled the Aqua subscription, since uninstalling the app doesn't stop billing.
Step 6 of the prompt has Claude stop and wait for you at the first two, and step 7 reminds you to cancel.
Speed and disk space on my M2 Pro
It costs nothing to run. The downloads are about 730 MB for Parakeet and 2.5 GB for Qwen3.
Ollama's log shows how long each Qwen3 4B cleanup took. Half came back in about a second or less, and one in ten took 6 seconds or more.
Downsides of running it all locally
- Fn only works as a shortcut on Apple keyboards: your Mac's own, or an Apple external one. On any other keyboard, pick another key.
- With keep-alive on, Ollama holds the model in memory all the time: about 5.3 GB on my Mac. Leave out the keep-alive setting if you'd rather have that back: Ollama unloads the model after 5 idle minutes, and the next cleanup waits while it loads.
- Handy saves the audio of every dictation, not just the text. Mine keeps the last 100, about 65 MB, in
~/Library/Application Support/com.pais.handy/recordings. - A 4B model only does light cleanup. It won't turn a ramble into a tidy email the way a big cloud model can.
Most of what I dictate is prompts for Claude Code, across a lot of sessions at once. Shabash, the Mac app I'm building, puts those sessions in one list with the ones that need me at the top.
