Ara — free, open, on-device dictation

Dictation that never leaves your Mac.

Hold fn, speak, release — the text lands at your cursor, cleaned up. Whisper transcribes on the Apple Neural Engine, an open 1.5B model does the editing, both on your machine. Free, MIT, no account, no subscription, no server.

curl -fsSL https://karniej.github.io/ara-parrot/install.sh | sh

It fetches the latest DMG, prints its checksum, and installs Ara.app. Or download it yourself, or build from source.

First launch with a large model spends a few minutes letting macOS prepare it for your Mac's Neural Engine — once per macOS version. Let it finish; quitting starts it over. On the default model that step takes about 11 seconds.

Builds are unsigned — no Apple Developer ID — so the first launch needs right-click → Open. Cleanup runs on a local model that is a separate one-time ~900 MB download.

macOS 14+ · Apple Silicon

Download →

Free, local, open

Everything that touches your voice runs on your machine, on open-weights models, at no cost. Whisper transcribes through WhisperKit on the Apple Neural Engine; Qwen 2.5 1.5B — Apache-licensed — strips fillers, punctuates and capitalises on MLX. No audio and no transcript leaves the Mac.

If a model is missing, slow or wrong, the transcript falls through to rule-based cleanup and is typed anyway. The language model is polish, not a dependency — nothing on any path loses your words.

Read the README →

$ ara --echo-transcripts

loading mlx-community/Qwen2.5-1.5B-Instruct-4bit (formatting)...

✓ mlx-community/Qwen2.5-1.5B-Instruct-4bit ready (1.0s)

listening on fn hold · model: whisper-base.en · ^C to quit

● recording

○ captured 3.90s · rms 0.041

→ 1.08s · um so we ship tuesday no wait wednesday

↦ 1.62s · We ship Wednesday.

● recording

○ captured 2.30s · rms 0.036

→ 0.71s · lets ship it in krakuf on friday

↦ 0.98s · Let's ship it in Kraków on Friday.

audio captured, raw transcript, after the dictionary and cleanup — printed only when they changed something. Illustrative session; times depend on the machine and the utterance. Without --echo-transcripts — the default, and always the case for the background daemon — those lines carry a character count instead of the text.

Speed is not the argument. This is.

Ara is a fork of digimata/parrot that grew a formatting layer, a vocabulary, and a menu bar. Here is what it does beyond turning speech into characters.

Cleanup on a local model

Fillers out, punctuation and capitalisation in, spoken self-corrections collapsed — “we ship Tuesday, no wait, Wednesday” becomes “We ship Wednesday.” Qwen 2.5 1.5B on MLX, on your Mac. No API key, no account, no request.

A cleanup dial, not a switch

none strips fillers only. light punctuates and keeps every spoken word. medium (default) removes fillers and obeys dictated “comma”, “period”, “question mark”. high restructures fragments into sentences and turns spoken enumerations into numbered lists.

Per-app tone

Default, email, chat and code modes, resolved from the app you are dictating into — or pinned for the session from the menu bar, which never overwrites your startup default.

A dictionary that sticks

Your name, your product, your city. Corrections are a deterministic pass that runs before any model sees the transcript, matched whole-word and case-insensitively. Plain JSON, re-read every utterance — add one and the next sentence is already fixed.

Voice snippets

Say a trigger phrase, get a block of text typed verbatim: a scheduling link, a sign-off, an address. It fires only when the whole utterance is the trigger, so a sentence that merely mentions it is formatted normally.

Paste or type, per app

Terminals and Electron apps silently mangle synthesized typing, so Ara pastes into those and types everywhere else. The paste path snapshots your pasteboard, keeps every representation of every item, refuses to restore a password manager's concealed copy, and stands down rather than clobber a ⌘C you just made.

A microphone that can be unplugged

Pin an input from the menu bar and it survives replug and reboot. Lose it mid-sentence and the utterance is not lost: recording continues on whatever input remains, and plugging one back in before you release resumes the same utterance.

A menu bar with every door

Microphone, cleanup, mode, model, hotkey, engine, dictionary, snippets, start at login, diagnostics. Each submenu states whether a pick applies to the next utterance or the next launch, so the menu never claims a change that has not happened.

Transcripts stay off disk

Log lines carry timing and a character count (→ 0.42s · 63 chars), never the words, unless you ask for them with --echo-transcripts. The background daemon never does. There is no server to send anything to.