How browser-native text-to-speech actually works
A tested explanation of the Web Speech API, where browser voices come from, what localService means, and which parts may still use a network.
By Wordcast | Published 2026-05-08 | Updated 2026-07-24 | 5 min read
The browser speech handoff
The page coordinates playback; the selected voice service creates the sound.
Text enters the page
Paste text, open a local file, or extract an article URL.
Chrome queues speech
SpeechSynthesisUtterance carries the language, rate, and voice.
The voice speaks
A local or remote service produces audio through the browser.
Browser-native text-to-speech is a handoff, not a single engine. A web page creates a speech request, the browser queues it, and the selected voice service turns the text into audio. The page can choose a voice, speed, pitch, and language, but it does not receive the generated audio. A local voice may synthesize on the device; a remote voice may contact its vendor. Fetching text from an article URL is a separate network step. Those boundaries matter more than the marketing label "browser TTS."
The browser surface is the speech-synthesis half of the Web Speech API. Three objects do most of the work. SpeechSynthesisUtterance holds the text and settings. window.speechSynthesis owns the queue and exposes speak, pause, resume, cancel, and getVoices. SpeechSynthesisVoice describes one choice returned by the browser. The minimal implementation really is short: create an utterance, set its text and optional voice, then pass it to speechSynthesis.speak. Chrome documented support for this flow in Chrome 33 in 2014.
Voice discovery is less predictable than the three-line example suggests. getVoices() returns the voices available on that browser and device, not a universal Chrome catalog. On a cold load it may initially return an empty array, so a production interface also listens for the voiceschanged event and checks again. A voice carries a name, language tag, default flag, URI, and localService flag. The browser vendor and operating system decide which voices appear, and that list can change after an OS update, a voice download, a browser update, or a policy change.
We checked the live list on July 24, 2026 using Chrome 150 on macOS. That one environment reported 180 voices across 49 language tags. All 180 reported localService=true, Samantha was the default, and there were no voices with "Google" in the name. This is useful because it disproves a common shortcut: desktop Chrome does not always expose a fixed set of Google voices. The result is a test record, not a promise about another computer. The reliable approach is to inspect getVoices() on the device the listener will actually use.
localService also needs careful wording. MDN defines it as a boolean indicating whether the voice is supplied by a local speech synthesizer service. A true value is a strong signal that synthesis is local, while false identifies a remote service. It is not an independent privacy audit, and it says nothing about how the text entered the page. In Wordcast, pasted text and local files are processed in the browser. An article URL is sent to an extraction service, and a remotely supplied voice may use its provider's network path for speech.
Playback is event-driven. An utterance can report start, pause, resume, end, error, and boundary events. A reader uses those events to keep its controls honest and to highlight the current sentence or word when the browser supplies usable boundary data. Boundary behavior varies by voice and browser, so highlighting should be treated as an enhancement rather than proof that speech is progressing. The speech queue also persists until it finishes or the page calls cancel, which is why changing documents without clearing the queue can produce apparently random old audio.
Long text exposes another implementation detail. A single large utterance can stall or end early in some Chrome and voice combinations; Chromium issue 679437 records the long-running cutoff discussion. Chunking text and advancing on end events reduces that failure mode and makes stop, pause, and progress easier to manage. It still cannot guarantee that an hour-long session survives device sleep, a tab suspension, a network-dependent voice failure, or a browser process restart.
The practical failure checklist is short. If there are no voices, wait for voiceschanged and retry getVoices. If pronunciation is wrong, choose a voice whose BCP 47 language tag matches the text. If the first tap is silent on a mobile browser, start speech directly from a real user gesture. If long text stops, use shorter utterances and listen for error and end rather than assuming the queue completed. If a selected voice disappears, fall back to the system default instead of keeping a stale voice URI.
The API's hard boundary is output. It plays speech through the browser, but it does not expose an audio buffer or an MP3 download. It also does not create a new voice, clone a speaker, perform OCR, or guarantee the same voice roster across devices. Those jobs require different tools. Browser speech synthesis is a good fit when the task is immediate listening and the user can accept the voices their current device provides.
Wordcast's implementation reflects those limits. It checks for voices immediately, listens for voiceschanged, polls briefly when a browser is slow to populate the list, prefers a matching local voice, and lets the user change the result. It offers sentence highlighting when the engine emits progress events. It does not add its own speech server or promise a fixed voice. That is what browser-native text-to-speech actually means: the page coordinates the experience, while the browser, operating system, and selected voice service do the speaking.
Sources and test notes
Product behavior was checked against the linked browser API documentation and the dated environment described in the article.