Skip to content

NativeTTS

Use the browser's built-in SpeechSynthesis API for text-to-speech with zero API keys or external dependencies.

Use NativeTTS when you need speech synthesis without API keys, external services, or peer dependencies. It wraps the browser’s SpeechSynthesis API and works offline in Chrome, Edge, and Safari.

Prerequisites

  • A browser that supports the SpeechSynthesis API (Chrome, Edge, Safari, Firefox)
  • No API keys required
  • No peer dependencies

Basic setup

import { CompositeVoice, NativeSTT, AnthropicLLM, NativeTTS } from '@lukeocodes/composite-voice';

const voice = new CompositeVoice({
  stt: new NativeSTT(),
  llm: new AnthropicLLM({
    proxyUrl: '/api/proxy/anthropic',
    model: 'claude-haiku-4-5',
  }),
  tts: new NativeTTS({
    voiceName: 'Samantha',
    rate: 1.0,
    pitch: 0,
  }),
});

await voice.start();

Configuration options

OptionTypeDefaultDescription
voiceNamestringundefinedPartial, case-insensitive match against available voice names
voicestring'default'Alias for voiceName
voiceLangstringundefinedBCP 47 language tag to filter voices (e.g., 'en-US', 'fr')
preferLocalbooleantruePrefer locally-installed voices (lower latency, works offline)
ratenumber1.0Speech rate multiplier
pitchnumber0Pitch in semitones (-20 to 20), normalized to the Web Speech range (0 to 2)

Voice selection follows this priority: name match, then language match, then local voice preference, then first available voice.

Complete example

import { CompositeVoice, NativeSTT, AnthropicLLM, NativeTTS } from '@lukeocodes/composite-voice';

const tts = new NativeTTS({
  voiceName: 'Google US English',
  voiceLang: 'en-US',
  preferLocal: true,
  rate: 1.1,
  pitch: 2,
});

const voice = new CompositeVoice({
  stt: new NativeSTT({ language: 'en-US' }),
  llm: new AnthropicLLM({
    proxyUrl: '/api/proxy/anthropic',
    model: 'claude-haiku-4-5',
  }),
  tts,
});

voice.on('agent:stateChange', ({ state }) => {
  console.log('State:', state);
});

await voice.start();

Voice enumeration

NativeTTS exposes the browser’s full voice list. Use this to build a voice picker or log what is available on the current device.

const tts = new NativeTTS();
await tts.initialize();

const voices = tts.getAvailableVoices();
voices.forEach((v) => {
  console.log(`${v.name} (${v.lang}) ${v.localService ? '[local]' : '[network]'}`);
});

// Switch voice at runtime
tts.setVoice('Google UK English Female');

Playback controls

NativeTTS manages its own audio — the browser plays speech directly through the device speakers. CompositeVoice does not receive audio data from this provider.

tts.pause();    // Pause current speech
tts.resume();   // Resume paused speech
tts.cancel();   // Stop and clear the utterance queue
tts.isSpeaking(); // true while speech is active
tts.isPaused();   // true while paused

Tips

  • Voice availability varies by browser and operating system. Always test on your target platform.
  • Local voices (localService: true) have lower latency and work offline. Set preferLocal: true to favor them.
  • NativeTTS is best suited for prototyping and demos. For production voice quality, consider DeepgramTTS.

Further reading

© 2026 CompositeVoice. All rights reserved.

Font size
Contrast
Motion
Transparency