Skip to main content
Early Beta — The Web SDK is in early beta. APIs may change between releases.

Overview

Browser text-to-speech uses Piper VITS voices in ONNX format, rendered by the sherpa-onnx WASM build in @runanywhere/web-onnx. A voice is a catalog model with category MODEL_CATEGORY_SPEECH_SYNTHESIS; there is no separate voice loader.

Registering a voice

Piper voices ship as .tar.gz bundles, so they register through registerModelArchive.

Voices in the example app

Piper publishes hundreds of voices across many languages. Browse the catalog at Piper Samples and register any of them the same way. Whatever you point at must be reachable from the browser, so it needs permissive CORS headers.

Loading and switching

Loading a speech-synthesis model replaces whichever voice was loaded for that category.
To free it:

Enumerating voices inside a model

A multi-speaker Piper model exposes several voices. RunAnywhere.tts.listLoadedVoices() returns what the currently loaded engine can render.
The list is empty when no TTS model is loaded or the WASM build lacks the enumeration export.

Selecting a voice or speaker

A voice id is not a model id. The model id names the downloaded bundle; the voice id names a voice inside it. Passing a model id as voiceId will not select anything.

Checking what is loaded

Handle API

RunAnywhere.tts also exposes a handle-based surface for callers that want to own the component lifecycle: create(), loadVoice(handle, path, id?, name?), isLoaded(handle), listVoices(handle), synthesize(handle, text, options?), synthesizeStream(handle, text, options?), stop(handle), unload(handle), and destroy(handle). Prefer the flat RunAnywhere.synthesize / speak path.

Synthesize

Text-to-speech synthesis

Streaming TTS

Chunked synthesis and playback

Voice agent

Full voice turn