SpeakEasy
Unified TTS

say("Simple text-to-speech for all your projects. Multiple providers, smart caching, and volume control.",
{ provider: 'openai', voice: 'nova' })
Try it now:
speakeasy "Welcome to SpeakEasy! This unified text-to-speech service makes it easy to add voice to your applications" --provider openai --voice nova --rate 180
npm install @arach/speakeasy

Start Speaking in Seconds

No complex setup, no boilerplate. Choose your style and start building.

import { say } from '@arach/speakeasy';

// Quick start - one line!
await say('Hello world!');

// With provider
await say('Hello from OpenAI!', 'openai');
await say('Hello from ElevenLabs!', 'elevenlabs');
import { speak, SpeakEasy } from '@arach/speakeasy';

// Full featured with options
await speak('Priority message', {
  provider: 'openai',
  volume: 0.8,
  priority: 'high'
});

// Custom instance
const speech = new SpeakEasy({
  provider: 'elevenlabs',
  volume: 0.6,
  rate: 200
});

await speech.speak('Custom configuration');
# Basic usage
speakeasy "Hello world"

# With volume control
speakeasy "Quiet message" --volume 0.3

# Multiple providers
speakeasy "Hello!" --provider openai --voice nova

# Cache management
speakeasy --cache --list
speakeasy --clear-cache
// ~/.config/speakeasy/settings.json
{
  "providers": {
    "openai": {
      "voice": "nova",
      "apiKey": "sk-..."
    },
    "elevenlabs": {
      "voiceId": "EXAVITQu4vr4xnSDxMaL",
      "apiKey": "sk-..."
    }
  },
  "defaults": {
    "provider": "openai",
    "volume": 0.7,
    "rate": 180
  }
}

Have Claude speak to you

Never miss important notifications. Transform Claude Code's silent alerts into intelligent spoken updates.

Tool Permission Request

Trigger: "Claude needs your permission"
What Claude shows:
Claude needs your permission
Audio Result
Loading waveform...
0:00 / 0:00
Visual Context
speakeasy --setup-hooks
Configure Claude Code notifications
⏺ Update(.claude/hooks/notif.ts)
⎿ Updated .claude/hooks/notif.ts with 10 additions
// ~/.claude/hooks/notification.ts
import { SpeakEasy } from '@arach/speakeasy';

const speakEasy = new SpeakEasy({
  provider: 'groq',
  cache: { enabled: true, ttl: '7d' },
  fallbackOrder: ['groq', 'openai', 'system']
});

// Read notification from Claude Code
const notificationType = process.argv[2];
const payload = JSON.parse(await readStdin());

// Extract project context
const projectMatch = payload.transcript_path?.match(/\/([^\/]+)$/);
const projectName = projectMatch?.[1] || 'your project';

// Transform into natural speech
let spokenMessage = payload.message;
if (projectName !== 'your project') {
  spokenMessage = `In ${projectName}, ${payload.message}`;
}

// Speak the notification
await speakEasy.speak(spokenMessage);

// Also copy to clipboard and log
await copyToClipboard(JSON.stringify(payload, null, 2));
logger.info('Notification processed', { type: notificationType, message: spokenMessage });
@arach/hooked

Ready-to-deploy handlers

ClaudeClaude Hooks

Official documentation