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.
Repository Health
Technical Analysis
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
ElevenLabsClientwith 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()andstream()wrapper functions for immediately playing back generated audio in Node (via MPV/ffmpeg) without hand-rolling audio-stream plumbing- A
SpeechEnginemodule (standalone WebSocket server orattach()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
maxRetriesandtimeoutInSeconds - 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.
Used by 2 apps in this directory
Activepieces
Automation · AI Assistants
Open-source AI automation platform that converts 280+ workflow integrations into MCP servers for LLMs, with no-code builders and TypeScript extensibility.
Flowise
Developer Tools · Automation · No Code Platforms
Drag-and-drop visual builder for AI agents, RAG pipelines, and multi-agent systems—deploy anywhere in minutes.