elevenlabs-js

The official Node.js SDK for the ElevenLabs voice AI API, covering text-to-speech, speech-to-text, dubbing, voice cloning, and real-time conversational agents in one typed client.

SDK
npm
v2.66.0
441stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
84/100Excellent
Development Activity84
Maintenance88
Community76
Maturity48
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
77/100Good
Architecture82
Code Quality78
Innovation68
Learning Curve80

elevenlabs-js is the official Node.js client for the ElevenLabs API, generated and maintained with Fern from ElevenLabs’ API definition. A single ElevenLabsClient exposes namespaced sub-clients — textToSpeech, speechToText, speechToSpeech, textToDialogue, voices, dubbing, studio, conversationalAi, and more — so every ElevenLabs product surface is reachable through one consistently-shaped, fully-typed API.

Beyond thin REST wrapping, the SDK ships purpose-built helpers for audio workflows: a play()/stream() pair for piping generated audio straight to playback, and a SpeechEngine module (both a standalone WebSocket server and an attach() helper for existing HTTP servers) for building custom-LLM voice agents where the SDK handles ElevenLabs’ speech-engine protocol, request signing, and transcript/response framing while the caller supplies the LLM turn. Requests are retried with exponential backoff on retryable status codes, and the client runs on Node, Vercel, Cloudflare Workers, Deno, and Bun.

What You Get

  • A single ElevenLabsClient with lazily-instantiated namespaced sub-clients for text-to-speech, speech-to-text, speech-to-speech, text-to-dialogue, voices, dubbing, studio, conversational AI, workspace/service accounts, and more
  • play() and stream() wrapper functions for immediately playing back generated audio in Node (via MPV/ffmpeg) without hand-rolling audio-stream plumbing
  • A SpeechEngine module (standalone WebSocket server or attach() to an existing HTTP server) for building custom-LLM voice agents, with built-in request-signature verification against ElevenLabs’ egress
  • Automatic retry-with-backoff on 408/409/429/5xx responses, configurable per-request maxRetries and timeoutInSeconds
  • Full TypeScript types for every request/response shape, generated directly from ElevenLabs’ API definition so they stay in sync with the API

Common Use Cases

  • Generating narration or voiceover audio from text with a selectable voice and model (e.g. eleven_multilingual_v2, eleven_flash_v2_5)
  • Building a voice AI agent that answers over a phone/WebSocket call, plugging a custom LLM into ElevenLabs’ Speech Engine via onTranscript
  • Transcribing speech to text or converting speech-to-speech for dubbing and localization pipelines
  • Cloning or searching a workspace’s voice library programmatically for use in an app’s TTS pipeline
  • Streaming low-latency audio to end users as it’s generated, rather than waiting for a full file

Under The Hood

Architecture The package is a Fern-generated SDK layered around a shared BaseClient/core module: ElevenLabsClient (src/Client.ts) lazily instantiates ~28 resource-specific clients (src/api/resources/*/client/Client.ts) on first property access, each of which builds requests through the shared core.fetcher, core.url, core.headers, and core.requestBody helpers rather than calling fetch directly. Hand-written ergonomics live in src/wrapper/ (ElevenLabsClient re-export, play.ts, stream.ts, music.ts, speechToText.ts, webhooks.ts, and the speech-engine/ and realtime/ subfolders), cleanly separating generated request/response plumbing from the small amount of bespoke logic (audio playback, WebSocket session management) that Fern can’t generate. Serialization/validation is centralized in src/serialization/, and typed errors (ElevenLabsError, ElevenLabsTimeoutError) are thrown consistently from every resource client, so swapping or regenerating the API surface doesn’t touch the runtime request layer.

Tech Stack TypeScript compiled with tsc (strict mode, isolated declarations) to CommonJS, using node-fetch as the default fetch implementation (falling back to a global fetch when present) plus ws for WebSocket-based streaming/realtime endpoints and command-exists to detect the MPV/ffmpeg binaries play() shells out to. Biome handles linting and formatting in place of ESLint/Prettier, Jest (with ts-jest and jest-environment-jsdom) runs both unit and “wire” test projects, and msw mocks HTTP calls in tests. CI (GitHub Actions) compiles, runs the full test suite against a live ELEVENLABS_API_KEY, and publishes to npm via OIDC-authenticated npm publish on tag push.

Code Quality Tests are organized into tests/unit (fetcher, file handling, form-data encoding, logging, schema serialization, URL building, wrapper helpers) and tests/wire/tests/custom, giving reasonably thorough coverage of the core request/response and serialization layers even though the generated resource clients themselves aren’t individually unit-tested. Error handling is explicit and typed throughout — every public method’s JSDoc documents its @throws types, and handleNonStatusCodeError centralizes non-HTTP failure translation. Naming is consistent generated-SDK style (resource/client/types per API resource), and strict: true plus isolatedDeclarations in tsconfig catches type issues at build time; Biome’s check/check:fix scripts enforce style in CI-adjacent tooling.

What Makes It Unique Most generated API SDKs stop at typed request/response wrapping; this one adds a hand-built real-time layer on top — SpeechEngine.Server/attach() implements ElevenLabs’ custom-LLM voice-agent protocol (session lifecycle, transcript delivery with an auto-aborting signal, streamed LLM-response forwarding, and signed-request verification) as first-class SDK surface, not a documented-but-unsupported side channel. Combined with the play()/stream() audio helpers, it turns “call the TTS endpoint” into “run a full duplex voice agent” without leaving the SDK.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search