TTS
Charivo's TTS layer combines @charivo/tts with a concrete player.
For production browser apps, use the remote player with a server route backed
by @charivo/server/openai.
Recommended Stack
@charivo/tts
@charivo/tts/remote
your /api/tts route
@charivo/server/openai
Basic Setup
import { Charivo } from "@charivo/core";
import { createTTSManager } from "@charivo/tts";
import { createRemoteTTSPlayer } from "@charivo/tts/remote";
const charivo = new Charivo();
charivo.attachTTS(
createTTSManager(createRemoteTTSPlayer({ apiEndpoint: "/api/tts" })),
);
Player Choices
Remote
@charivo/tts/remote- production-oriented browser path
- sends text and voice options to your own API route
Direct OpenAI
@charivo/tts/openai- useful for local development and testing
- exposes credentials to the browser
Browser-Native
@charivo/tts/web- built on the Web Speech API
- useful for prototypes and zero-server flows
- voice behavior depends on browser and OS support
What @charivo/tts Owns
- playback lifecycle
- lip-sync event emission
- player capability normalization through
playbackModeand optionalaudioMimeType
TTSManager intentionally uses setEventEmitter(...), not the full event bus.
It emits TTS lifecycle and lip-sync events back into core, but it does not
subscribe to upstream Charivo events.
Provider Route
The remote player usually pairs with @charivo/server/openai on the
server:
const provider = createOpenAITTSProvider({
apiKey: process.env.OPENAI_API_KEY!,
defaultVoice: "marin",
defaultModel: "gpt-4o-mini-tts",
});
const audio = await provider.generateSpeech(text, {
voice: "marin",
rate: 1,
});
Alternatives
- Use
@charivo/tts/webwhen you want no backend and browser variability is acceptable. - Use
@charivo/tts/openaiwhen you are debugging OpenAI TTS behavior directly. - Skip TTS when text chat is enough for the current experience.