Push-to-talk dictation for macOS.
Hold a key, speak, release — your words appear in whatever app you're typing in.
Vietnamese-first, English-friendly. Current release 0.3.10. Powered by Kyma API.
haynoi.com · Download for macOS
Most dictation tools treat Vietnamese as an afterthought. Haynoi is built for the way Vietnamese people actually speak — tiếng Việt with English mixed in mid-sentence ("deadline", "deploy", "team marketing") — and keeps both languages intact instead of translating or mangling one of them.
- Speaks your language(s). Vietnamese-optimized speech-to-text that handles Vi/En code-switching — and a personal dictionary that learns from your corrections, so names and jargon come out right the next time without you configuring anything.
- Works in every app. Text is inserted directly where your cursor is — editor, browser, chat, terminal — via the Accessibility API, with clipboard fallback.
- Nothing to paste. Sign in once with Google. No API keys. Free tier included; Quality transcription is the default.
Hold ⌥ → speak → release → text appears
Two steps after you release:
- Listen — Haynoi transcribes what you said (Quality by default, or Fast).
- Rewrite — in Email / Formal (and Auto in a mail app: Mail, Gmail, Outlook, Spark, Superhuman). Your spoken draft is turned into a professional message. If that polish step fails or times out, the original transcript is still pasted — you don't lose the words.
While you hold, a small overlay pulses and shows a live caption of what you are saying; a layered chord confirms start and stop. Full notes: CHANGELOG.
| Mode | What it does |
|---|---|
| Normal | Transcribes what you say and applies your dictionary. No rewrite |
| Clean | Like Normal, and drops filler words (ừm, à, uh…) at transcription time |
| Email / Formal | Transcribe, then rewrite into a professional message |
| Auto | Picks a mode from the app you're in — Email in mail apps, Clean in chat |
Haynoi's dictionary fills itself instead of asking you to maintain it:
- Fix it once, it sticks. Say "fix that" (⌃⌥) and re-dictate, edit the inserted text in place, or just repeat yourself — Haynoi notices the correction and suggests remembering it. Confirmed fixes are applied automatically from then on, and they survive a restart.
- It knows when it wasn't sure. When the transcriber hesitates on a word that sounds like a name you use — "Afider" for "Affitor", "Sun" for "Sơn" — that one dictation gets an extra cleanup pass with your personal terms. Confident dictations skip it, so nothing gets slower.
- You can see if a fix is earning its keep. A learned replacement shows how often it was applied once it has fired, and how often you kept it once you have undone it at least once. The Dictionary header sums that up.
- You stay in charge. A master learning switch, a counter of what's been learned, and a one-tap "Forget all" live in Settings → Dictionary. Learning runs on transcript text only — never audio — and your dictionary never leaves your Mac.
- Push-to-talk — hold the left
⌥Option key (or⌘/⌃/fn), release to transcribe - Language preference — auto-detect by default, or pin Tiếng Việt / English
- Failed dictations are saved — if the network dies mid-upload, the recording stays on your Mac and retries with one click
- Email polish never eats the draft — if rewrite fails, the raw transcript is still inserted
- Honest errors — a server problem is labeled as ours. It does not tell you that you're out of words, and it does not sign you out
- Survives real life — AirPods disconnecting mid-sentence, permission hiccups, and flaky Wi-Fi all degrade gracefully instead of eating your dictation
- Auto-paste into the active app, with clipboard fallback — and your previous clipboard is restored afterwards (dictated text is also hidden from clipboard managers). In-place replace (“fix that”) needs the target to expose a text field to macOS Accessibility (
AXValueand a caret range). GPU/PTY terminals and similar views do not; there “fix that” inserts the corrected text at the cursor and leaves the old text for you to delete. - Other audio gets out of your way — music and video pause and resume around your dictation; a live call or stream is dipped in volume instead, decided from what your Mac is actually playing
- Living status orb — recording, transcribing, success, and error each have their own state
- Snippets — say a trigger word, get expanded text
- Transcription history — searchable, stored locally, grouped by date
- Test connection in Settings → Account (doesn't use your word quota)
- Premium sound feedback — harmonic chords for start / stop / cancel / success
- Silent auto-updates via Sparkle, launch at login, guided onboarding
Download Haynoi 0.3.10 (Haynoi.dmg) from haynoi.com or GitHub Releases, drag it to Applications, and open it. The app is signed and notarized — no security warnings, and updates install themselves.
Prefer building from source?
git clone https://github.com/sonpiaz/haynoi.git
cd haynoi
brew install xcodegen # if not installed
make runFirst run, either way:
- The onboarding wizard walks you through Microphone and Accessibility permissions — that's all Haynoi needs
- Sign in with Google — one click, no passwords, nothing to paste
- Hold the left
⌥Option key, say something, release — the guided first dictation shows you the loop
Runs on Kyma API. Kyma handles speech-to-text and rewrite for every dictation so Haynoi never holds a model key.
Free: 5,000 words per week, resetting every Monday. No card required — just Google sign-in.
Haynoi Pro (unlimited words) is coming soon.
Two listening tiers, switchable in Settings. A text model handles the Email / Formal rewrite and the correction pass:
| Step | Setting | Model | Best for |
|---|---|---|---|
| Listen | Quality (default) | gpt-4o-mini-transcribe-2025-12-15 |
Vietnamese + English, noisy rooms, technical vocabulary |
| Listen | Fast | whisper-v3-turbo |
Clear, simple speech |
| Rewrite | Email / Formal, and the correction pass when the transcriber flags a word | gemini-3.5-flash-lite |
Email: turn a spoken draft into a message. Correction pass: fix flagged words with your terms, no rephrasing. If either step fails, the original transcript is still pasted. |
Haynoi calls these through Kyma API so the app never holds a model key.
- Audio is sent to Haynoi's backend for transcription, then discarded — recordings are never stored server-side
- Your dictionary, learned corrections, and transcription history stay on your Mac — learning uses transcript text only, never audio, and nothing about it syncs anywhere
- Your sign-in session lives in the macOS Keychain
- Anonymous usage analytics (feature counts and timings — never your words, never transcript content) help improve the app; there's an opt-out toggle in Settings
make generate # Generate Xcode project (XcodeGen)
make build # Build via xcodebuild
make run # Build and run
make clean # Clean build artifactsProject structure
Sources/Haynoi/
├── App/
│ ├── HaynoiApp.swift — App entry, menu bar, onboarding
│ ├── AppState.swift — Shared state, transcription history
│ └── PipelineController.swift — Hotkey → Record → Transcribe → Insert
├── Audio/
│ ├── AudioRecorder.swift — 16kHz mono mic capture via AVAudioEngine
│ └── SoundFeedback.swift — Harmonic chord audio cues
├── Auth/
│ ├── HaynoiAuth.swift — Google sign-in via Haynoi's backend
│ └── KeychainStorage.swift — Session storage in the macOS Keychain
├── Input/
│ ├── HotkeyManager.swift — Global hotkey via NSEvent monitors (Accessibility)
│ └── TextInserter.swift — AX API + clipboard text insertion
├── Transcription/
│ ├── STTProvider.swift — Transcription, Email rewrite, correction pass
│ └── TranscriptionMode.swift — Normal / Clean / Email / Auto modes
├── Settings/
│ └── SettingsView.swift — Account, plans, quality, hotkey, dictionary
├── UI/ — History list, main window, floating bar
└── System/ — Personal dictionary + correction learning,
media control, launch at login, usage stats
| Technology | Purpose |
|---|---|
| Swift 5.9 + SwiftUI | App |
| AVFoundation | Audio capture & sound synthesis |
| Kyma API | Speech-to-text (gpt-4o-mini-transcribe-2025-12-15 / whisper-v3-turbo) and rewrite (gemini-3.5-flash-lite) |
| Accessibility API + NSEvent | Text insertion + global hotkey (no Input Monitoring needed) |
| XcodeGen | Project generation |
- Pheme — AI meeting notes for macOS, Vietnamese-optimized
- kyma-dub — time-aligned AI video dubbing CLI
- Kapt — macOS screenshot tool with annotation & OCR
MIT — see LICENSE.