Wordcast
Back to blog

Which browser voices stay on your device, and which do not

Some Web Speech API voices synthesize your text on your machine. Others send it to a server first. Here is the one property that tells you which is which, and how to check it yourself.

2026-05-20 · 5 min read

5 min listen

When you pick a voice in a browser text-to-speech tool, you are making a privacy decision without knowing it. Some voices turn your text into audio entirely on your own machine. Others quietly send that text to a server, wait for the audio to come back, and play it. Both feel identical when you press Listen. The difference only matters if the text is something you would not paste into a stranger's search box.

The Web Speech API gives you exactly one signal to tell them apart. Every voice returned by speechSynthesis.getVoices() carries a boolean property called localService. When it is true, the browser is promising that this voice runs on-device: your text does not leave the page. When it is false, the voice is remote, and the browser has to ship your text somewhere else to synthesize it. That single flag is the whole distinction between private and networked speech.

The pattern is easiest to see in desktop Chrome. The voices whose names begin with 'Google' — 'Google US English', 'Google UK English Female', and the rest — are almost always remote. They are high-quality neural voices, and they sound it, but their localService value is false because Chrome fetches the audio from Google's servers. That is why those voices stop working the moment you go offline, and why the same voice list can look different depending on your connection.

The operating system voices tell the opposite story. On macOS and iOS, the system voices derived from Siri report localService as true and run on-device, which is why they keep speaking on a plane with the Wi-Fi off. Windows is split down the middle: the older SAPI voices like David and Zira are offline and local, while the newer voices labeled 'Natural' or 'Online' are cloud-backed and report localService as false. The naming is a decent hint on Windows, but the property is the real answer, since Microsoft ships both kinds under similar-looking labels and only localService distinguishes them reliably.

You do not have to take anyone's word for this, including mine. Open your browser's developer console on any page and run speechSynthesis.getVoices().filter(v => v.localService) to list the voices that stay on your device, then run speechSynthesis.getVoices().filter(v => !v.localService) to see the ones that reach out to a server. On some browsers the list loads asynchronously and comes back empty on the very first call, because the browser populates it in the background and fires a voiceschanged event when it is ready. So if you get nothing, trigger any speech once and run the filter again. The two lists together are your personal map of which voices are safe for private text, and if a tool shows you no voices at all, that empty-list timing is usually the reason rather than a missing feature on your machine.

So how should you actually choose? If the text is sensitive — a private message, a medical note, an unpublished draft, anything you would not want logged on a server you do not control — pick a voice where localService is true and keep the whole process on your device. If the text is already public, like a news article or a blog post, the remote voices are a fine trade: you get noticeably better audio in exchange for text that was never secret in the first place, and the round trip to a server costs you nothing you were trying to protect. There is no single correct answer, only the right one for the specific text in front of you.

Here is the honest limit. localService is a hint the browser sets, not a legal guarantee or an audited privacy contract. It reflects how the browser vendor has wired up that particular voice, and that wiring can change between operating system versions and browser releases. A voice that runs locally today could, in principle, be reimplemented differently later. The flag is the best signal the platform gives you, and it is usually accurate, but it is a description of behavior rather than a promise about it. If your text is genuinely confidential, treat on-device synthesis as strongly preferable rather than as proof.

Wordcast reads the localService property straight from your browser and shows you the voices your device already has, so you are choosing from the same list you could print in the console yourself. The tool does not add voices, upload anything on its own, or route your text through a service of its own — whatever your browser decides to do with a given voice is exactly what happens, which is the point.

The takeaway is small and practical. There is a real line between voices that speak on your machine and voices that speak through a server, that line is a single boolean you can inspect in about ten seconds, and for anything you would not want leaving your device, checking it once is worth the trouble.