vue-text-to-speech
v2.0.5
Published
Vue 3 text-to-speech plugin with composables, UI components, and multi-provider support
Maintainers
Readme
vue-text-to-speech
Vue 3 text-to-speech plugin with composables, drop-in components and multi-provider support — Web Speech API, OpenAI, ElevenLabs and Azure Cognitive Services, all behind one unified interface.
📖 Documentation · 🛝 Live Playground · 📦 NPM
Features
- 🎙️ Four providers — Web Speech (zero config), OpenAI, ElevenLabs, Azure
- ⚡ Composable-first —
useSpeechSynthesis,useSpeechRecognition,useStreamingTTS,useVoiceQueue - 🤖 LLM streaming — pipe
AsyncIterable<string>token streams directly to speech - 🧩 Drop-in components —
VueSpeechPlayer,VueSpeechRecorder,VueSpeechVoiceSelect - 🔒 Security-first —
baseURLoverride on all AI providers for server-side proxying - 📘 TypeScript — full declarations shipped, no
@types/*needed - 🧪 207 tests — Vitest + @vue/test-utils, SSR-safe
Installation
npm install vue-text-to-speech
# pnpm add vue-text-to-speech
# yarn add vue-text-to-speechQuick Start
// main.ts
import { createApp } from 'vue'
import { VueSpeech } from 'vue-text-to-speech'
import App from './App.vue'
createApp(App)
.use(VueSpeech, { provider: 'web' })
.mount('#app')<script setup lang="ts">
import { useSpeechSynthesis } from 'vue-text-to-speech'
const { speak, stop, isSpeaking } = useSpeechSynthesis()
</script>
<template>
<button @click="speak('Hello, world!')">Speak</button>
<button @click="stop()">Stop</button>
</template>AI Providers
// OpenAI
createApp(App).use(VueSpeech, {
provider: 'openai',
apiKey: import.meta.env.VITE_OPENAI_KEY,
voice: 'nova',
model: 'tts-1-hd',
}).mount('#app')
// ElevenLabs
createApp(App).use(VueSpeech, {
provider: 'elevenlabs',
apiKey: import.meta.env.VITE_ELEVEN_KEY,
voiceId: 'EXAVITQu4vr4xnSDxMaL', // default voice; find IDs at elevenlabs.io/voice-library
}).mount('#app')
// Azure Cognitive Services
createApp(App).use(VueSpeech, {
provider: 'azure',
subscriptionKey: import.meta.env.VITE_AZURE_KEY,
region: 'eastus',
voice: 'en-US-JennyNeural',
}).mount('#app')⚠️ Never expose API keys in the browser. Use the
baseURLoption to proxy requests through your server. See the Security Guide.
LLM Streaming
import { useStreamingTTS } from 'vue-text-to-speech'
const { pipeStream, isStreaming, stop } = useStreamingTTS()
// Pipe any AsyncIterable<string> — tokens are split into sentences
// and spoken as they form using Intl.Segmenter
await pipeStream(myOpenAIStream())Speech Recognition (STT)
import { useSpeechRecognition } from 'vue-text-to-speech'
const { start, stop, isListening, transcript, finalTranscript } =
useSpeechRecognition({ lang: 'en-US', continuous: true })Always uses the browser's SpeechRecognition API regardless of the TTS provider configured.
Drop-in Components
<!-- Full player: voice select + sliders + controls -->
<VueSpeechPlayer text="Hello from vue-text-to-speech!" />
<!-- Mic button with live transcript -->
<VueSpeechRecorder @final-transcript="onTranscript" />
<!-- Standalone voice selector (pair with useSpeechSynthesis) -->
<VueSpeechVoiceSelect v-model="selectedVoice" :voices="voices" :loading="isLoadingVoices" />Register all three components globally in one go:
createApp(App)
.use(VueSpeech, { provider: 'web', components: true })
.mount('#app')Documentation
Full API reference, provider guides and integration examples:
👉 vue-text-to-speech-docs.vercel.app
Live Playground
Try all providers and components in the browser:
👉 vue-text-to-speech-playground.vercel.app
Changelog
See CHANGELOG.md for release history and migration notes from v1.
License
MIT © kunchamvasu
