TreeMap
A free, open-source disk-space visualizer. Squarified treemap, duplicate hunting, disk-full forecasting, and cleanup that only ever moves files to the Trash.
Voice dictation for Mac and Windows that runs entirely on your own machine. Open source, no account, no subscription.
ProductivitySwift · TypeScriptGitHub @getfreeflowOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Local-first voice dictation for macOS. On-device Whisper, bring your own API key.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Voice dictation for macOS that runs on your own machine. Hold a key, talk, and the text
appears wherever your cursor is.
Transcription happens locally with a Whisper model. No audio leaves your Mac, there's no
account, and nothing is metered. An optional cleanup pass turns the raw transcript into text
you can actually send, using an API key you supply.Read the full README ↗Voice dictation for macOS that runs on your own machine. Hold a key, talk, and the text appears wherever your cursor is.
Transcription happens locally with a Whisper model. No audio leaves your Mac, there's no account, and nothing is metered. An optional cleanup pass turns the raw transcript into text you can actually send, using an API key you supply.
Dictation. Hold the trigger key and talk. Release, and the text is inserted at your
cursor. Double-tap the key instead to lock recording on; the notch drops down with a discard
and an insert button, and one more tap stops it. esc throws the take away.
Commands. Select text anywhere, hold the command key, and say what you want done to it. "Cut this in half." "Make these bullets." The result replaces the selection. With nothing selected you get an answer instead, inserted at the cursor.
Meetings. Records both sides of a call from your Mac's audio output. Nothing joins the call and no one is notified. Audio is transcribed on-device and written up with the points, decisions and follow-ups. You can ask questions about anything you recorded.
Style. Per-app rules for how it writes, because a line in a chat window and a paragraph in a document shouldn't sound the same. Ships with defaults; all editable.
Vocabulary. The words it keeps getting wrong: your name, your colleagues, product names, acronyms.
Snippets. Say two words, insert a paragraph. Expanded before cleanup runs, so the result still gets shaped for wherever it's going.
Actions. Saved instructions you can apply to any text, from inside the app or by name while dictating. Shorten, Formal, Friendly, Bullets, Fix grammar, Summarize, and your own.
Scratchpad. A page that's always open for thoughts without a home yet.
Insights. What you dictated per day, how fast you speak, where the words went.
Plus searchable history, launch at login, three model sizes, and a fully offline mode.
macOS 14 or later. Apple Silicon recommended. To build you need Xcode 15+ and
XcodeGen (brew install xcodegen).
On Windows, there's a separate build in windows/: Electron,
whisper.cpp, and the same hold-to-talk loop. It covers dictation and cleanup, not the
meeting recorder or the rest of the Mac feature set.
git clone https://github.com/getfreeflow/freeflow.git
cd freeflow && ./install.sh
That generates the project, builds it, copies the app to /Applications and opens it. The
.xcodeproj is generated rather than committed, so the checkout stays clean. To work on the
code instead, xcodegen generate && open FreeFlow.xcodeproj and press Run.
Worth doing before you grant anything.
By default the app is ad-hoc signed, which needs no setup but has an unpleasant consequence. An ad-hoc signature is a hash of the binary, so it changes on every build, and macOS identifies apps to TCC (Accessibility, Input Monitoring, Microphone) by that signature. Every rebuild looks like a new app, and the permissions you granted belong to a build that no longer exists. The switches stay on in System Settings while the running app is refused. Reinstalling is the cause, not the cure.
Signing with a certificate replaces that hash with the certificate's, which never changes.
Create one. It's self-signed and never leaves your Mac:
printf '[req]\ndistinguished_name=dn\nx509_extensions=ext\nprompt=no\n[dn]\nCN=FreeFlow Local Signing\n[ext]\nbasicConstraints=critical,CA:false\nkeyUsage=critical,digitalSignature\nextendedKeyUsage=critical,codeSigning\n' > /tmp/ff.cnf
openssl req -newkey rsa:2048 -nodes -keyout /tmp/ff-key.pem -x509 -days 7300 -out /tmp/ff-cert.pem -config /tmp/ff.cnf && openssl pkcs12 -export -inkey /tmp/ff-key.pem -in /tmp/ff-cert.pem -out /tmp/ff.p12 -passout pass:freeflow -name "FreeFlow Local Signing" && security import /tmp/ff.p12 -k ~/Library/Keychains/login.keychain-db -P freeflow -T /usr/bin/codesign -A
Importing sets the key's ACL but not its partition list, which is a separate gate. Without
this next step codesign is refused with errSecInternalComponent. It will ask for your
login password:
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -l "FreeFlow Local Signing" ~/Library/Keychains/login.keychain-db
Point the build at it:
echo 'CODE_SIGN_IDENTITY = FreeFlow Local Signing' > Support/Signing.local.xcconfig && xcodegen generate
That file is gitignored, so nothing machine-specific gets committed. Rebuild and check:
codesign -d -r- /Applications/FreeFlow.app
You want identifier "com.freeflow.FreeFlow" and certificate leaf = H"...". If you see
cdhash instead, it's still ad-hoc.
Finally, clear the entries the old ad-hoc builds left behind. There is one per past build, and they are why System Settings can show a permission as granted while the app disagrees:
for s in Accessibility ListenEvent Microphone; do tccutil reset $s com.freeflow.FreeFlow; done
Grant the three permissions once after that and you're done with this permanently.
The certificate is untrusted by Gatekeeper standards, which is fine here. codesign accepts
it and TCC only cares that the leaf hash is stable. It is not a substitute for a Developer ID
if you ever want to hand the app to someone else.
Pick your keys. fn is the default because nothing competes for it. Right-Option and
Right-Control also work well.
If you pick fn, take it back from macOS first. It's assigned to Dictation or Emoji by
default and that assignment wins:
System Settings → Keyboard → "Press 🌐 key to" → Do Nothing
Grant access to the Microphone, Accessibility (to place text into other apps), and Input Monitoring (to see the trigger key). Meetings additionally needs Screen Recording, which is how macOS gates system audio; it's requested the first time you record one.
Pick a model. Downloaded once with a progress readout, then cached.
| Model | Size | |
|---|---|---|
large-v3-turbo | ~1.5 GB | Most accurate, still fast on Apple Silicon |
small.en | ~500 MB | Lighter, stumbles more on names |
base.en | ~150 MB | Fastest and roughest, for older hardware |
Optionally add a key. Cleanup, commands, actions and meeting summaries go through Groq, which has a free tier and needs no card. Without one dictation still works; you get the transcript as spoken.
In ~/Library/Application Support/FreeFlow/credentials.json, owner-only (0600). Never in
this repository, never in a plist, never in the app bundle. There are no credentials in this
codebase at all, which is what makes it safe to fork.
It is not encrypted at rest. Any process running as your user can read that file. This was a
deliberate trade. macOS ties Keychain access to an app's code signature, and a project you
build yourself gets a new signature on every rebuild, so the Keychain treats each build as a
different app and asks for your login password on launch, repeatedly. For a build-it-yourself
app that isn't usable. If you'd rather have Keychain storage and don't mind re-authorising
after each rebuild, SecretFile in
CredentialStore.swift is the only thing to change.
Turn Cleanup off in Settings and the app makes no network requests at all.
key down ──▶ AudioRecorder AVAudioEngine → 16 kHz mono Float32
key up ──▶ Transcriber WhisperKit, on-device, streaming partial text
├▶ Vocabulary your spellings restored
├▶ Snippets spoken shorthand expanded
├▶ GroqClient cleanup via your Style rules, or a command
└▶ TextInjector Accessibility write, else clipboard + ⌘V
Three things in the source worth knowing about:
HotkeyMonitor watches .flagsChanged rather than
.keyDown.The event tap is .listenOnly, so it observes without consuming and nothing you already use
breaks. Insertion tries a direct Accessibility write first, which leaves the clipboard
untouched, and falls back to clipboard plus synthetic ⌘V, which works essentially everywhere
including Electron apps. If nothing focused can accept text, the transcript is left on the
clipboard rather than pasted into nowhere.
Meetings uses ScreenCaptureKit, the only sanctioned route to system audio on current macOS. A 2×2 video stream is requested because a content filter is mandatory; the video is discarded.
/Applications.Any language other than English, iOS or Android, team features.
There is no download. You build it yourself, which takes about ten minutes, most of it waiting. Shipping a binary that runs on someone else's Mac without a Gatekeeper warning requires a paid Apple Developer account for notarization, and this project doesn't have one.
1. Install the two build tools. Xcode from the App Store, then:
brew install xcodegen
2. Get the code.
git clone https://github.com/getfreeflow/freeflow.git && cd freeflow
3. Set up a signing certificate. Optional, but do it now rather than later. Without it macOS forgets your permissions every time you rebuild. The commands are in Making permissions stick above. Skip only if you plan to build once and never touch it again.
4. Build and install.
./install.sh
This builds the app, copies it to /Applications and opens it. The first build downloads
WhisperKit and takes a few minutes. Later builds are quick.
5. Open it from /Applications from then on, not from Xcode. macOS assigns permissions
per app location, so grants made to a copy run from Xcode won't follow it, and
launch-at-login only works from there.
6. Free up the fn key. macOS assigns it to Dictation or Emoji by default and that
assignment wins over anything this app does:
System Settings → Keyboard → "Press 🌐 key to" → Do Nothing
Skip this if you chose a different trigger key.
7. Grant three permissions when the app asks: Microphone, Accessibility, and Input Monitoring. All three are in System Settings → Privacy & Security. After granting Input Monitoring, quit and reopen the app; macOS only reads that one at launch.
8. Pick a model in onboarding and let it download. large-v3-turbo unless you're on
older hardware. This happens once.
9. Optionally paste a Groq key from console.groq.com/keys. Free, no card. Without one you get raw transcripts instead of cleaned-up text, and command mode is unavailable.
Then hold your trigger key and talk.
The last step opened a folder instead of an app. You ran open FreeFlow.xcodeproj on a
Mac without Xcode. A project is a folder on disk, and only Xcode teaches Finder to treat it
as anything else. Install Xcode from the App Store, open it once, then run ./install.sh.
The key does nothing. Input Monitoring isn't granted, or fn is still bound to Dictation
in System Settings. The app's dashboard shows which permission is missing.
Permissions look granted but the app disagrees. Stale TCC entries from earlier ad-hoc
builds. Fix the signing certificate, then run the tccutil reset line from
Making permissions stick.
Text doesn't appear. Accessibility isn't granted. If it's granted and text still goes missing in one specific app, turn off direct write in Settings so it uses clipboard paste instead.
Nothing is transcribed. Check the model finished downloading on the dashboard.
Issues and pull requests welcome. This is a personal project released for free. There's no company behind it, no paid tier planned, and no telemetry of any kind.
Speech recognition by WhisperKit from Argmax. Interface tokens adapted from shadcn/ui. Icons from Lucide (ISC, with a few from Feather under MIT; notices are in Icons.swift). Language model calls go to Groq.
Independent and unaffiliated. Not connected to, sponsored by, or endorsed by any commercial dictation product.
MIT, see LICENSE.