Voice input in the browser is a study in inconsistency.
Chrome, Edge, and most Chromium-based browsers have the Web Speech API with continuous recognition that works well for dictation. Firefox ships a stub that throws a not-supported error at runtime. Safari's implementation works but requires a permission gesture every few sentences. And all of them send your audio to a cloud service.
When I built voice dictation for PromptBoard, I needed something that worked everywhere and ran locally. Transcriber is the answer: a Node.js server that runs Whisper in-process and exposes a single HTTP endpoint. Any browser tool that wants voice input sends audio there and gets text back.
The cascade
Every Machina tool that supports voice uses the same three-level cascade:
Level 1 — Web Speech API (Chromium)
If window.SpeechRecognition is available, use it. Zero latency, zero network. Happy path for Chrome users.
Level 2 — Transcriber (port 4324)
For Firefox, MediaRecorder captures audio as a webm blob. On stop, it's POSTed to /transcribe. Transcriber converts to WAV with ffmpeg, runs Whisper, returns text. Round-trip: 1–3 seconds.
Level 3 — Manual fallback
If Transcriber isn't running and Web Speech isn't available, a dialog opens with the recorded audio and a textarea. Nothing is silently lost.
The API
GET /health → { ok, ready, model, language }
POST /transcribe → { ok, text } (body: raw audio bytes)
POST /shutdown → graceful stop
Small surface, single responsibility. Transcriber doesn't manage sessions, doesn't store audio, doesn't know which tool is calling it.
The model downloads on first run (~150MB for whisper-base) and caches locally. You can swap models via env var:
TRANSCRIBER_MODEL=Xenova/whisper-small # better accuracy, ~460MB
TRANSCRIBER_MODEL=Xenova/whisper-tiny # faster, ~75MB
Transcriber is part of Machina — a free, open-source suite of AI developer tools.
Top comments (1)
Local transcription is underrated for browser AI tools because it changes the trust model, not only the latency. A small local Whisper backend gives you consistent behavior across browsers and avoids sending raw audio to a third party just to fill a text box.