| Dictate anywhere | Click where you'd normally type, hold ⌘ Right, speak, release. The text lands almost instantly. |
| Local-first | Ships with Parakeet for speech and a small Gemma model for rewrites. Both run on your Mac. |
| Learns your vocabulary | Teammates, internal jargon, products, vendor names. Correct one out loud, once, and it stays fixed. |
| Fast | Text lands at your cursor in under half a second for most dictations, up to about two seconds for harder ones. |
| Programmable and promptable | Build transforms out of substitutions, prompts, or scripts, and arrange them into your own pipeline. |
ParrotFlow requires Apple silicon and macOS 14 or later. Both routes install the
same app. Take Homebrew if you already use it — upgrading and removing go
through brew. Otherwise run the script.
Homebrew
brew install znat/tap/parrotflowScript
curl -fsSL https://raw.githubusercontent.com/znat/parrotflow/main/scripts/install.sh | shNeither one downloads the speech model. ParrotFlow fetches Parakeet itself the first time it launches, about 470 MB, and says how far along it is.
Spoken commands and the transforms that are prompts need a language model as well, and that part is optional. Your vocabulary does not: that stage reads the sentence itself and calls nothing. Run a model on your own Mac with Ollama (e.g. Gemma4), or use a hosted one (e.g. OpenAI).
Parakeet, NVIDIA's speech model, runs locally and fast. Most dictations land in under half a second.
Everything else — the hotkey, the pipeline, every transform — lives in one
plain YAML file, config.yaml you can edit it by hand or with your coding agent.
To find it: the 🦜 icon in the menu bar → Settings → Edit Config…
Use regexes, scripts or prompts to customize your dictations.
Example: add PR links to your dictations
transforms:
- name: github_refs
description: spoken PR and issue numbers as links
replace:
'[#$1](https://github.com/OWNER/REPO/pull/$1)':
['/\b(?:pull request|PR)\s*(?:(?:number|nr|no|hash)\s+)?#?(\d+)\b/']"merged P R one two three, ready to ship" → "merged #123, ready to ship", where #123 links straight to the pull request.
The rule writes a Markdown link and the paste turns it into a real one — see
bullets, bold and links. The
spoken digits are already 123 by then: the built-in numbers stage turned
"one two three" into it first.
Example: Automatically add Slack handles.
transforms:
- name: slack_handles
description: use Slack handles for the people named
command: slack_handles.pyWhere slack_handles.py is:
#!/usr/bin/env python3
# roster.json sits beside this file: {"Ada": "@ada.lovelace", ...}
import json, pathlib, re, sys
roster = json.loads((pathlib.Path(__file__).parent / "roster.json").read_text())
text = sys.stdin.read()
for name, handle in roster.items():
# Skip a name already written as a handle, and a name used as an
# ordinary word — "mark it as done" is a verb.
text = re.sub(rf"(?<![@\w.]){re.escape(name)}\b", handle, text, flags=re.I)
sys.stdout.write(text)Combine transforms in a pipeline
transcription:
pipeline:
- numbers # "one two three" -> 123, so github_refs has digits
- transform: github_refs
- transform: slack_handlesAdd models to your config:
models:
gemma: # on your Mac, through Ollama
api: ollama
model: gemma4:e4b-mlx
default: true # what a transform runs on when it names no model
gpt: # remote, for the harder jobs
api: openai
model: gpt-5.6-lunaA small local model, like Gemma, does quick, solid rewrites on your Mac: grammar, tone, structure.
transforms:
- name: grammar
description: fix grammar and punctuation
model: gemma # stays on your Mac
offer: true # put a chip on the pill after every dictation
key: g # press G to run it
prompt: Fix grammar and punctuation...Say "hey parrot, fix the grammar", or press G on the pill after any
dictation.
Or you can run the grammar fix in chat and mail apps (but not in coding agents, for instance) for all dictations:
transcription:
pipeline:
- transform: grammar
app: /slack|outlook/ # Grammar only checked in Slack and OutlookSee examples/transforms/grammar for a more elaborate version.
A remote model for harder jobs. A spoken correction needs judgment a fixed rule or a too small local model does not have.
transforms:
- name: self_correction
description: correct me — drop what I said by mistake and keep what I meant
model: gpt
offer: true # put a chip on the pill
key: s # press S to run it
prompt: |
The speaker corrected themselves out loud. Keep only what they meant
to say. Return only the corrected text.Say "hey parrot, correct me", or press S on the pill after any
dictation. A longer version, tuned and scored against real transcripts, is in
examples/transforms/self_correction.
Colleagues' names, internal jargon, acronyms, vendor names — the words a general speech model has never heard. Correct it a few times and it stays fixed.
Press V on the pill after any dictation and say what the word should be.
The stage reads the sentence before it writes a name: there is no Vercel Castle, and Versailles won't deploy your apps. It does that without a model — two word lists, the part of speech the slot wants, and two tests that compare the sentence with the ones the term was confirmed in.
transcription:
pipeline:
- vocabulary
- numbersEach with its own test cases, in examples/transforms:
- code_identifiers — spoken names
cased for the language, "a python function called max retries" →
max_retries. - repetitions — drops disfluencies, a word said twice by accident: "the the prompt" → "the prompt".
- punctuation — spoken marks as punctuation, "is that true question mark" → "is that true?".
- self_correction — the prompt above, and the 89 cases it is scored on: "my config my vocabulary" → "my vocabulary".
Pipelines · Writing a transform · Where the time goes
Tip
Point your coding agent at this
repo and say what you want. It can edit config.yaml, write a transform's
prompt or script, and harden it against real test cases before you trust
it — start at AGENTS.md.
docs/README.md — configuration, pipelines, transforms, the command line, permissions, architecture.
CONTRIBUTING.md — build it, test it, send a change. Questions that are not bugs go to Discussions.
The parrot is by Md Moniruzzaman, from the Noun Project, used under CC BY. The outline is his; the plumage is ours — see docs/development.md.
macOS dictation · offline speech to text · local voice typing · open source Wispr Flow alternative · privacy-first transcription · Parakeet · Ollama






