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.
翻译准备中
Free, open-source, 100% offline AI dictation for Windows & macOS. Wispr Flow / Dragon alternative. Push-to-talk hotkey, voice commands, transforms, sub-second latency. Powered by Whisper. No cloud, no subscription, no telemetry.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Free, Open-Source, 100% Offline AI Dictation for Windows & macOS
Press a hotkey. Speak. Your words appear at the cursor.
No cloud. No subscription. No telemetry. Powered by OpenAI Whisper.
Quick Start · Features · vs. Wispr Flow / Dragon · Voice Commands · Contributing
Want a real screen-recording demo here? See docs/demo-recording.md — drop a docs/demo.gif in and uncomment the line below.查看完整 README ↗Press a hotkey. Speak. Your words appear at the cursor. No cloud. No subscription. No telemetry. Powered by OpenAI Whisper.
Quick Start · Features · vs. Wispr Flow / Dragon · Voice Commands · Contributing
macOS, or Python on either: pipx install whisper-local then whisper-local
Windows 10+ · macOS · nothing to sign up for · first launch downloads one 141 MB model, then it is offline for good · all releases
Want a real screen-recording demo here? See docs/demo-recording.md — drop a docs/demo.gif in and uncomment the line below.
Whisper Local is a free, open-source, fully offline alternative to Wispr Flow, Dragon, and Otter for power users who want AI dictation without sending audio to the cloud. Built on faster-whisper (CTranslate2), it delivers push-to-talk speech-to-text in any application — chat apps, code editors, browsers, terminals, design tools, anywhere a cursor blinks. Self-hosted, hackable, MIT-licensed.
Looking for: Wispr Flow alternative, offline voice typing, local Whisper dictation, free Dragon NaturallySpeaking alternative, privacy-first speech-to-text, Windows voice dictation without cloud, macOS push-to-talk transcription. You found it.
Most AI dictation tools are great — until you check the privacy policy. Your audio goes to a server, gets processed, and (sometimes) stored. You pay a monthly fee or get cut off.
Whisper Local exists because you shouldn't have to choose between accuracy and privacy.
This is a community tool, not a product. There's no support SLA, no roadmap committee, no marketing. If it's useful to you, great. If something's broken, PRs are welcome.
A note from the maintainer: I built this for myself, then realised it might help others. So I'm releasing it for anyone who wants it — no strings attached. Use it. Fork it. Rebrand it. Ship your own version. The only thing I ask is that you keep the LICENSE notice intact. If you build something cool on top of it, I'd love to hear about it via a Discussion — but you don't owe anyone anything.
— Rohit Burani
| Feature | Whisper Local | Wispr Flow | Dragon / Dragon Anywhere | Otter.ai | Windows Speech Recognition (deprecated) |
|---|---|---|---|---|---|
| Runs 100% offline | ✅ | ❌ | ❌ (Anywhere) | ❌ | ✅ |
| Audio never leaves your machine | ✅ | ❌ | ❌ | ❌ | partial |
| Free, with no usage cap | ✅ | ❌ (free tier is capped) | ❌ ($$$/yr) | ❌ ($$/mo) | ✅ |
| Open source | ✅ | ❌ | ❌ | ❌ | ❌ |
| Modern AI speech recognition | ✅ (Whisper) | ✅ (its own Canto model) | partial | ✅ | ❌ |
| Auto-cleanup levels, per-app styles, snippets, backtrack | ✅ | ✅ | partial | ❌ | ❌ |
| Works in any app via hotkey | ✅ | ✅ | partial | ❌ | partial |
| Customisable voice commands | ✅ | partial | ✅ | ❌ | ❌ |
| Push-to-talk + auto-paste + auto-send | ✅ | ✅ | partial | ❌ | ❌ |
Ctrl+Win (Windows) or Fn+Ctrl (macOS)postprocess.inline_formatting_replacements (e.g. map Polish phrases to punctuation, or "arrow" → →)whisper.languages: [en, fr]) and auto-detection picks only from those, so a short or accented clip is never transcribed as a language you don't speak. Speak one that isn't on the list and it asks whether to add itnone / light / medium / high decides how much gets tidied: stutters and "um" go by default, "scratch that" and "meet at 2, actually 3" from medium up. See Smart editingpostprocess.list_formatting, opt-in)whisper-local.exe from the latest release.Every .exe is built by GitHub Actions from this repository and carries a signed build-provenance attestation. To confirm a download is genuine, run gh attestation verify whisper-local.exe --repo drajb/whisper-local, or compare its SHA-256 with the .sha256 file on the release page.
pipx install whisper-local # or: uv tool install whisper-local
whisper-local
Plain pip install whisper-local works too. pipx (or uv tool) gives the app its own environment, which keeps it clear of whatever else is installed; a PyTorch install in a shared environment, for example, is the usual reason a Python app takes a minute to start.
git clone https://github.com/drajb/whisper-local.git
cd whisper-local
pip install -e .
| Terminal | whisper-local (or wl for short) |
| Double-click | whisper-local.cmd (Windows) |
| Start on login | Tick Start on login in the tray menu (or the first-run welcome), or run whisper-local --enable-autostart. Disable anytime the same way. |
First launch downloads the default base Whisper model (~141 MB) into your HuggingFace cache. After that, everything runs offline. (Prefer a smaller/faster download? Set whisper.model: tiny — ~75 MB.)
huggingface.coblocked at work? Common on corporate networks. Export the model from a machine that has internet and import it on the one that doesn't — no admin rights needed:whisper-local --export-model # machine WITH internet — writes to your Desktop whisper-local --import-model "<the folder you copied over>" # the offline machinePass a path to
--export-model(a USB drive, say) to put it somewhere else. Network-share and internal-mirror setups are covered in docs/offline-models.md.
| Action | Windows | macOS |
|---|---|---|
| Hold to record | Ctrl+Win | Fn+Ctrl |
| Stop & paste | release key (push-to-talk) or Ctrl | release or Fn |
| Stop & auto-send (Enter) | Alt | Option |
| Cancel | Esc | Shift |
| Voice command mode | Alt+Win | Fn+Command |
whisper-local --doctor
Runs through Python version, dependencies, config validation, audio devices, model cache, hotkey backend, and recent log errors. Exit 0 = clean.
Say it naturally; it gets typed the way you'd have written it. Everything runs offline, with no LLM. One setting, Cleanup (Settings → Post-process, or postprocess.cleanup), picks how much gets tidied:
| Cleanup | What changes |
|---|---|
none | exactly what Whisper heard |
light (default) | stutters ("I I think") and "um" / "uh" are dropped |
medium | light, plus "scratch that" and "at 2, actually 3" |
high | medium, plus spoken times, emails and web addresses |
| You say | You get | Needs |
|---|---|---|
| "I I think we we should go" | I think we should go | light |
| "Let's meet at 2, actually 3" | Let's meet at 3 | medium |
| "Ship it Tuesday, no wait, Wednesday" | Ship it Wednesday | medium |
| "book the flight, scratch that, cancel it" | cancel it | medium |
| "john at example dot com at 3 pm" | [email protected] at 3 PM | high |
| "Groceries: first, milk. Second, eggs." | Groceries:1. Milk2. Eggs | postprocess.list_formatting |
| "Thanks for your help. My signature." | Thanks for your help. Best,Rohit | postprocess.snippets |
Any single toggle can still be pinned on or off in user_settings.yaml regardless of the level. Backtrack only acts when a cue ("actually", "I mean", "no wait", "sorry", …) is followed by a number, time, weekday or month that replaces an earlier one in the same sentence, so everyday prose like "I actually like it" is never changed.
Snippets are defined once:
postprocess:
snippets:
- trigger: my signature
expansion: "Best,\nRohit"
- trigger: my address # mode: alone = only when it's the whole dictation
expansion: "1 Main St, Dallas, TX 75201"
mode: alone
Styles set capitalization and punctuation in one choice: formal (full sentences), casual (no trailing period), very_casual (all lowercase except acronyms and your own terms) and verbatim (no automatic capitals, periods or lists). Set postprocess.style globally, or style: on a rule in app_rules.yaml. The shipped rules make email formal, chat casual, and code editors and terminals verbatim.
Speak a trigger to run keyboard shortcuts, type snippets, or launch programs. Defined in:
%APPDATA%\whisperkey\commands.yaml~/.whisperkey/commands.yamlcommands:
# Send a keyboard shortcut
- trigger: "undo"
hotkey: "ctrl+z"
# Deliver pre-written text
- trigger: "my email"
type: "[email protected]"
# Run a shell command
- trigger: "open notepad"
run: 'notepad.exe'
Edits hot-reload — no app restart required. See docs/voice-commands.md for the full guide.
⚠️ Voice commands with
run:execute through your system shell with your user privileges. Only add commands you trust.
On first launch, Whisper Local detects your GPU and offers one-press install of the required runtime libraries. Supports NVIDIA CUDA and AMD ROCm.
For manual setup or AMD RDNA 1, see docs/gpu-setup.md.
Whisper Local doubles as a drop-in local replacement for the OpenAI Whisper API — fully offline. Point any tool that speaks POST /v1/audio/transcriptions at it (Cursor, VS Code Continue, Open WebUI, n8n, custom scripts, anything else).
whisper-local --serve # listens on http://127.0.0.1:7777
whisper-local --serve --serve-port 8080
# Drop-in compatible with the OpenAI SDK:
curl -X POST http://127.0.0.1:7777/v1/audio/transcriptions \
-F [email protected] -F model=whisper-1 -F response_format=text
Same Whisper model you use for dictation. Same GPU. No API key. No rate limit. No outgoing traffic.
Switch between presets from the tray icon → Profile:
| Profile | Behaviour |
|---|---|
| Dictation | General-purpose voice typing, auto-paste on |
| Chat | Push-to-talk, auto-paste + auto-send via Alt |
| Code | Copy-only mode for editors, never auto-sends |
| Notes | Quiet copy-to-clipboard, voice commands disabled |
Edit or add new profiles in %APPDATA%\whisperkey\profiles.yaml.
Different apps want different behaviour. Whisper Local detects the
foreground window before delivering each transcription and matches it
against rules in %APPDATA%\whisperkey\app_rules.yaml:
rules:
# Chat apps: send the message immediately
- match: ["slack.exe", "discord.exe"]
auto_send: true
# Code editors: copy only, and keep it verbatim (no auto-caps or trailing period)
- match: ["code.exe", "cursor.exe"]
auto_paste: false
capitalize_first: false
ensure_punctuation: false
# Password managers: skip delivery entirely
- match: ["1password.exe", "bitwarden.exe"]
suppress: true
A rule can override delivery (auto_send, auto_paste, suppress), Whisper
context (initial_prompt, language, task), and formatting
(capitalize_first, ensure_punctuation, strip_trailing_period,
inline_formatting). Hot-reloads — edit and the next transcription picks it up.
If you have Ollama running locally, Whisper Local can
pipe each transcript through a small local model for punctuation and
capitalisation polish. Off by default and fully local — set
postprocess.ollama.enabled: true in user_settings.yaml to enable.
postprocess:
capitalize_first: true # works without Ollama
ensure_punctuation: true # works without Ollama
strip_filler_words: true # works without Ollama
ollama:
enabled: false # set true to opt in
endpoint: http://localhost:11434
model: llama3.2
timeout: 5
Local settings live at:
%APPDATA%\whisperkey\user_settings.yaml~/.whisperkey/user_settings.yamlDelete the file and restart to reset to defaults. Highlights:
| Option | Default | Notes |
|---|---|---|
whisper.model | base | Any model from whisper.models. tiny = smallest/fastest, larger = more accurate/slower |
whisper.device | cpu | cpu or cuda (NVIDIA/AMD) |
whisper.compute_type | int8 | int8/float16/float32 |
whisper.language | auto | Auto-detect or specific language code |
whisper.hotwords | [] | Words the model should favour — names, jargon |
whisper.languages | [] | The languages you dictate in, e.g. [en, fr]: auto-detection picks only from these |
hotkey.recording_hotkey | ctrl+win | Configurable |
hotkey.recording_mode | push_to_talk | push_to_talk (hold to talk) or toggle |
hotkey.double_tap_to_lock | false | Double-tap the record hotkey for hands-free recording |
hotkey.paste_last_hotkey | alt+shift+z | Type your last dictation again (ctrl+option+v on macOS) |
postprocess.cleanup | light | none / light / medium / high: how much of what you said gets tidied |
postprocess.style | "" | formal / casual / very_casual / verbatim, or per app in app_rules.yaml |
history.retention_days | null | 0 stores no history at all; 7 keeps a week |
Full reference: config.defaults.yaml.
whisper-local # Run the app (or use `wl`)
whisper-local --setup # Interactive setup wizard (model, mode, mic)
whisper-local --doctor # Run diagnostics
whisper-local --stats # Transcription history & time saved
whisper-local --version # Print version
whisper-local --quit # Stop the running instance
whisper-local --export-settings DIR # Back up user_settings + commands
whisper-local --import-settings DIR # Restore from a backup
whisper-local --export-transcripts FILE # Dump history (.txt/.md/.csv)
whisper-local --import-vocab FOLDER # Mine a folder for hotwords
whisper-local --settings # Open the settings GUI (no YAML editing required)
whisper-local --history # Browse and search transcript history
whisper-local --cheat-sheet # Show your currently configured hotkeys
whisper-local --selftest # Run an automated self-test (mic, model, transcription)
whisper-local --bundle-logs # Create a redacted diagnostic zip for bug reports
whisper-local --serve # Run a local OpenAI-compatible Whisper API on :7777
whisper-local --enable-autostart # Launch automatically at login (--disable-autostart to undo)
whisper-local --test # Run a separate test instance (own mutex)
Launching while an instance is already running takes over — the old one is replaced cleanly, no manual quit needed.
┌─────────────────────┐ ┌──────────────────┐ ┌─────────────────────┐
│ global-hotkeys / │ │ sounddevice + │ │ faster-whisper / │
│ NSEvent (macOS) │─▶│ 500ms ring buf │─▶│ ctranslate2 (GPU) │
└─────────────────────┘ │ + TEN VAD │ └──────────┬──────────┘
└──────────────────┘ │
▼
┌──────────────────┐ ┌─────────────────────┐
│ Voice command │◀─│ Transcribed text │
│ matcher │ │ │
└──────────────────┘ └──────────┬──────────┘
▼
┌─────────────────────┐
│ ctypes SendInput / │
│ Quartz CGEvent │
│ → cursor │
└─────────────────────┘
Whisper Local makes the following network calls and no others:
huggingface.co into your local cache.pip install pulls CUDA / ROCm runtime packages from PyPI / repo.radeon.com.api.github.com for the latest release tag. Nothing but the app version leaves the machine.localhost unless you change it.During dictation, zero network traffic. Every entry point is in onboarding.py, update_check.py and text_postprocess.py, and each is gated behind an explicit setting or prompt. Search the source for urllib if you'd rather check.
faster-whisper · ctranslate2 · sounddevice · ten-vad · pyperclip · pystray · ruamel.yaml · playsound3
Windows-only: global-hotkeys · pywin32 · ctypes SendInput
macOS-only: pyobjc-framework-Quartz · pyobjc-framework-ApplicationServices
.exe, PyPI, winget, Homebrew) and how to ship oneHit a wall? Run whisper-local --doctor or whisper-local --selftest first — they catch 90% of issues.
Contributions of all kinds are welcome — bug fixes, new features, docs improvements, or just opening an issue with a clear reproduction. This project is maintained on a best-effort basis with no SLA; please be patient with response times.
git clone https://github.com/drajb/whisper-local.git
pip install -e .
python -m unittest tests.test_smoke # smoke suite — should report OK
See CONTRIBUTING.md for the full guide and CODE_OF_CONDUCT.md for community standards. By contributing you agree your code will be MIT licensed. Found a security issue? See SECURITY.md — please don't open a public issue.
Good first issues are tagged here. The full credit list is in AUTHORS.md.
Whisper Local is free and always will be. If it saves you time or a monthly subscription, consider starring the repo and sharing it with people who'd find it useful — it helps the project grow.
No pressure. Starring the repo and sharing it with people who'd find it useful is just as helpful.
Whisper Local builds on a lot of excellent open-source work. The full list is in AUTHORS.md.
MIT licensed; see LICENSE.
Maintained by Rohit Burani (@drajb)
Website · GitHub · Discussions · Report a bug · Request a feature
Tags: whisper · dictation · speech-to-text · voice-typing · transcription · ai-dictation · local-ai · offline · push-to-talk · voice-recognition · accessibility · faster-whisper · privacy · self-hosted · wispr-flow-alternative · dragon-naturallyspeaking-alternative · otter-alternative · ollama · voice-commands · windows · macos · python
| GPU acceleration (NVIDIA & AMD) |
| ✅ |
| n/a |
| n/a |
| n/a |
| ❌ |
| AI rephrase / transforms (Ollama) | ✅ | ✅ | ❌ | ❌ | ❌ |
| Hackable / MIT licensed | ✅ | ❌ | ❌ | ❌ | ❌ |
| No account required | ✅ | ❌ | ❌ | ❌ | ✅ |
${date} / ${time} / ${clipboard} filled inAlt+Shift+Z types your last dictation again when it landed in the wrong windowhotkey.double_tap_to_lock, opt-in)audio.whisper_mode, opt-in)postprocess.smart_formatting, each toggle opt-in)Ctrl+Shift+Win hotkey: select text, hold, speak your instruction, release — local Ollama rewrites it in placeCtrl+Alt+Win (or the tray's Pause hotkeys) disables every Whisper Local hotkey until you press it againhistory.retention_days)commands.yaml and your change applies on the next transcription, no restartwhisper-local --doctor checks audio devices, model cache, hotkeys, and recent errorsstreaming.deliver_to_cursor commits finalized phrases to the cursor live, Wispr-Flow style (trades full-Whisper accuracy for latency; see docs/streaming.md)--export-settings / --import-settings for portabilitywhisper-local --settings opens a GUI settings window (no YAML editing required)whisper-local --history opens a searchable log of everything you've dictatedCAPEX: [cap x, copics]), applied in a single pass with longest-match-winswhisper-local --transcribe-system transcribes what you hear (meetings, videos), not just the mic (pip install 'whisper-local[loopback]', Windows-first)update_check.enabled: true to opt in)noisereduce, off by default (pip install 'whisper-local[noise]')--selftest — one-command sanity check (mic, model, transcription, clipboard) — perfect for first-launchwhisper-local --cheat-sheet or tray menu — shows your current configured hotkeys at a glance--bundle-logs — zip up redacted logs + diagnostics for bug reports with one commandwhisper-local --serve exposes POST /v1/audio/transcriptions on localhost:7777 for Cursor, Open WebUI, anything that speaks OpenAI Whisper APIstats.typing_wpm | 40 | Your typing speed, used for the "minutes saved" estimate |
postprocess.snippets | [] | Spoken shortcuts expanded inline |
audio.whisper_mode.enabled | false | Boost quiet speech before transcription |
vad.vad_realtime_enabled | true | Auto-stop on silence |
clipboard.auto_paste | true | false = copy only |
clipboard.delivery_method | paste | paste (Ctrl+V) or type (direct injection) |
voice_commands.enabled | true | Enable command mode |
audio.host | null | WASAPI recommended on Windows for low latency |