Open-source real-time voice dictation for macOS, Windows & Linux — speak and the text lands at your cursor. A free, cross-platform alternative to Wispr Flow & superwhisper, with cloud engines (Gemini, Mistral, OpenAI, Groq) or 100% local Whisper.
English · Français · 🌐 Website & documentation
🤖 Open source, fully built with AI — and we own it. Sonora was designed and coded end to end by an AI agent (architecture, Rust/Tauri backend, Svelte 5 frontend, CI/CD, brand design), paired with a human who steered and tested on their machine. The code, the commits and this README are the result of that collaboration. Take it as a demonstration of what can be built this way — with its strengths… and the need to review anything security-related.
A Spotlight-style floating bar, always a shortcut away. You press, you speak, the text appears live — then it's copied to the clipboard or typed straight at your cursor. Plug in the engine of your choice: Gemini, Mistral, OpenAI, Groq, any OpenAI-compatible endpoint, or fully local, offline Whisper.
- 🎙️ Streaming dictation — text appears as you speak (with Gemini Live).
- ⌨️ Type at cursor — the result is typed where you are (or copied to the clipboard).
- ⌘ Global shortcut — start/stop without leaving your current app.
- 🔌 Pluggable models — Gemini Live, Mistral (Voxtral), OpenAI Whisper, Groq, OpenAI-compatible, local Whisper.
- ✦ Hesitation cleanup — optional pass that strips "uh", false starts, repetitions.
- ✍️ Reformulation prompts — transform a dictation through an LLM with your own prompts ("rewrite formally", "convert to a terminal command", "make it professional"…).
- 🕘 History — find and re-copy your previous dictations.
- 🌗 Theme — light / dark / system.
- 〰️ Live waveform driven by the real audio level.
- 🔐 API keys in the keychain — stored in the OS keyring (
0600file fallback), never in plaintext on the frontend. - 🖥️ Cross-platform — a lightweight binary (Tauri) on macOS, Windows and Linux.
| Provider | Transcription | Reformulation | Key required | Offline |
|---|---|---|---|---|
| Gemini Live | streaming, word-by-word | ✓ | yes | — |
| Mistral (Voxtral) | per segment | ✓ | yes | — |
| OpenAI Whisper | per segment | ✓ | yes | — |
| Groq Whisper | per segment | ✓ | yes | — |
| OpenAI-compatible | per segment | ✓ | host-dependent | possible |
| Local Whisper (ggml) | per segment | — | no | ✓ |
"Per segment" transcription splits speech with voice-activity detection (VAD) and transcribes each segment; Gemini Live instead streams the text continuously.
Prerequisites: Rust (stable), Bun, and the Tauri system dependencies (WebKitGTK, etc.).
bun install
bun run tauri dev # development
bun run tauri build # production build (binary in src-tauri/target/release/sonora)NixOS / Nix — the flake exposes a native package (recommended on NixOS over the AppImage, which trips on EGL/bubblewrap drivers):
nix run github:Devitek/sonora # run directly
nix build github:Devitek/sonora # -> ./result/bin/sonora…and a complete devshell (WebKitGTK, ALSA, cmake, wtype…) for development:
nix develop
bash scripts/dev.sh # frees a stale Vite port, then runs `tauri dev`Open the Settings (⚙ icon on the bar):
- Choose a transcription provider.
- Paste the matching API key (stored in the OS keychain).
- Optional: pick the microphone (capture source; "System" follows the OS default mic, ↻ refreshes the list).
- Optional: model, language, base URL (compatible endpoints),
ggmlmodel path (local Whisper). - Optional: enable automatic cleanup, choose its reformulation engine, and define your custom prompts.
For development, these settings can also come from a
.envfile (see.env.example).
Sonora is a transparent, decoration-less, focus-less window. Under a tiling
compositor like Hyprland, float it and bind the global shortcut. Syntax for recent
Hyprland versions (match: selector):
windowrule = float on, match:title ^(Sonora)$
windowrule = move (monitor_w/2)-240 40, match:title ^(Sonora)$
windowrule = border_size 0, match:title ^(Sonora)$
windowrule = no_shadow on, match:title ^(Sonora)$
windowrule = rounding 0, match:title ^(Sonora)$
windowrule = no_blur on, match:title ^(Sonora)$
windowrule = pin on, match:title ^(Sonora)$
windowrule = no_initial_focus on, match:title ^(Sonora)$
# Push-to-talk: launch a 2nd instance that forwards the action to the running one (single-instance)
bind = SUPER, V, exec, sonora toggle- CI (
.github/workflows/ci.yml): on every push/PR, Svelte type-check +cargo fmt+clippy -D warnings+cargo checkon Windows and macOS. Plus the Nix build, CodeQL analysis and dependency audits (cargo audit/bun audit). - Release (
.github/workflows/release.yml): Actions → Release → Run workflow with a semver bump (patch/minor/major) → versions, tagsvX.Y.Z, and publishes Linux (.AppImage,.deb), macOS (.dmg, Apple Silicon + Intel) and Windows (.msi, NSIS) binaries on the GitHub Release.
Contributions are welcome! See the contributing guide (setup, verification commands, conventions, the permissions/platforms golden rule). To report a bug or request a feature, open an issue with the right template.
Visual assets in brand/:
logo.svg— icon (gradient, rounded background) ·logo-mark.svg/logo-mark-white.svg— symbol only- Colors: purple
#7C5CFF→ cyan#22D3EE· dark background#0A0B12 - Typography: Space Grotesk (titles) · Inter (UI) · JetBrains Mono (details)
MIT © 2026