npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zyther/voice

v0.1.0

Published

Provider-agnostic TypeScript core for text-to-speech and speech-to-text.

Readme

@zyther/voice

Núcleo TypeScript provider-agnostic para Text-to-Speech (TTS) e Speech-to-Text (STT).

Estado atual: fundação do MVP com providers OpenAI, ElevenLabs e Deepgram. O Deepgram inclui transcrição REST e streaming WebSocket.

Instalação

npm install @zyther/voice

Uso

import { createVoice } from "@zyther/voice";
import { MyProvider } from "./my-provider.js";

const voice = createVoice({ provider: new MyProvider() });

const audio = await voice.tts({
  text: "Welcome to Zyther!",
  language: "en-US",
  voice: "default",
  format: "mp3",
});

const transcription = await voice.stt({
  audio: audio.audio,
  language: "en-US",
  format: audio.format,
});

console.log(transcription.text);

Provider OpenAI

O provider real usa os endpoints oficiais /v1/audio/speech e /v1/audio/transcriptions. A chave pode ser fornecida explicitamente ou pela variável OPENAI_API_KEY.

import { createVoice, OpenAIVoiceProvider } from "@zyther/voice";

const voice = createVoice({
  provider: new OpenAIVoiceProvider({
    // Opcional quando OPENAI_API_KEY está configurada.
    apiKey: process.env.OPENAI_API_KEY,
    ttsModel: "gpt-4o-mini-tts",
    sttModel: "gpt-transcribe",
  }),
});

O TTS aceita mp3, opus, wav e pcm. Para STT, esta primeira integração aceita mp3 e wav, conforme os formatos documentados para transcrição de arquivos. O campo language é usado como dica no STT; no TTS, o idioma é inferido do texto pelo serviço.

Os testes do provider usam um fetchImpl injetado e não fazem chamadas à OpenAI. A aplicação deve tratar VoiceProviderError, inclusive respostas como autenticação, limite de uso e indisponibilidade.

OpenAI GPT Realtime

O mesmo provider também expõe streamSTT() e streamTTS() através do WebSocket Realtime. A transcrição usa uma sessão type: "transcription" com gpt-live-transcribe; a síntese usa uma sessão type: "realtime" com gpt-4o-realtime-preview por padrão. Os modelos, voz, URL e sample rate são configuráveis.

const realtimeVoice = new OpenAIVoiceProvider({
  apiKey: process.env.OPENAI_API_KEY,
  realtimeModel: "gpt-4o-realtime-preview",
  realtimeTranscriptionModel: "gpt-live-transcribe",
  realtimeVoice: "alloy",
  realtimeSampleRate: 24000,
});

async function* pcmInput() {
  yield pcmChunk1;
  yield pcmChunk2;
}

for await (const partial of realtimeVoice.streamSTT(pcmInput(), { language: "pt-BR" })) {
  console.log("transcrição:", partial.text);
}

for await (const pcm of realtimeVoice.streamTTS({ text: "Olá!", format: "pcm" })) {
  playPcm(pcm);
}

O áudio Realtime deve ser PCM mono little-endian na taxa configurada, normalmente 24 kHz, e é enviado em Base64 dentro dos eventos JSON. Em browser ou mobile, não exponha uma chave persistente: use uma chave efêmera emitida pelo backend ou prefira WebRTC. A opção webSocketImpl permite injetar um transporte que implemente headers de servidor quando necessário.

Provider ElevenLabs

O provider ElevenLabs usa síntese avançada com vozes selecionáveis e os endpoints /v1/text-to-speech/{voice_id}, /v1/speech-to-text e /v1/voices.

import { createVoice, ElevenLabsVoiceProvider } from "@zyther/voice";

const voice = createVoice({
  provider: new ElevenLabsVoiceProvider({
    // Também pode ser definido em ELEVENLABS_API_KEY.
    apiKey: process.env.ELEVENLABS_API_KEY,
    voiceId: process.env.ELEVENLABS_VOICE_ID,
    ttsModel: "eleven_multilingual_v2",
  }),
});

const audio = await voice.tts({
  text: "Olá, bem-vindo à Zyther!",
  language: "pt-BR",
  voice: "voice-id-opcional",
  format: "mp3",
});

const voices = await voice.getVoices("pt-BR");

O TTS aceita mp3, opus, wav e pcm. O formato detalhado enviado à ElevenLabs pode ser customizado por outputFormat, por exemplo mp3_44100_128. O STT usa o modelo scribe_v2 por padrão e aceita os formatos definidos pelo contrato do package. A ElevenLabs pode retornar confiança de idioma, que é normalizada em STTResponse.confidence.

Provider Deepgram

O provider Deepgram é especializado em transcrição: usa POST /v1/listen para arquivos completos e o WebSocket wss://api.deepgram.com/v1/listen para áudio em tempo real. A autenticação REST usa Authorization: Token ...; no WebSocket, o provider usa o subprotocolo token, API_KEY, compatível com browser e Node.

import { createVoice, DeepgramVoiceProvider } from "@zyther/voice";

const voice = createVoice({
  provider: new DeepgramVoiceProvider({
    // Também pode ser definido em DEEPGRAM_API_KEY.
    apiKey: process.env.DEEPGRAM_API_KEY,
    model: "nova-3",
    interimResults: true,
    smartFormat: true,
  }),
});

const transcript = await voice.stt({
  audio: wavBytes,
  format: "wav",
  language: "pt-BR",
});

async function* microphone() {
  yield firstPcmChunk;
  yield secondPcmChunk;
}

for await (const partial of voice.streamSTT(microphone(), { language: "pt-BR" })) {
  console.log(partial.text);
}

streamSTT() encaminha chunks binários, emite resultados parciais e finais e envia Finalize/CloseStream ao terminar a fonte. webSocketImpl pode ser injetado para runtimes específicos ou testes. O provider Deepgram atualmente não oferece TTS; chamar tts() retorna um erro explícito de capability.

Criando um provider

Um provider implementa VoiceProvider. O contrato mínimo exige tts() e stt(); streaming, listagem de vozes e detecção de idioma são capacidades opcionais. Assim, uma integração real pode evoluir sem acoplar a aplicação ao fornecedor.

import type { VoiceProvider } from "@zyther/voice";

export class MyProvider implements VoiceProvider {
  readonly name = "my-provider";

  async tts(request) {
    // Chamada ao fornecedor e normalização da resposta.
    return { audio: new Uint8Array(), format: request.format ?? "mp3", provider: this.name };
  }

  async stt(request) {
    // Chamada ao fornecedor e normalização da transcrição.
    return { text: "...", provider: this.name };
  }
}

O MockVoiceProvider existe apenas para testes locais e não produz áudio real.

Scripts

Na pasta do package:

npm run test:unit        # testes unitários, sem chamadas externas
npm run test:integration # testes live, requer credenciais válidas
npm run typecheck
npm run build            # dist + declarações TypeScript

Os testes live são opt-in e podem consumir créditos. Configure OPENAI_API_KEY, ELEVENLABS_API_KEY + ELEVENLABS_VOICE_ID e/ou DEEPGRAM_API_KEY antes de executá-los.

Próximos passos

Adicionar adapters de Web Streams/Node streams, testes de integração opcionais e o serviço HTTP da Zyther Voice API. Consulte ../../ROADMAP.md.