svelte/elevenlabs
v0.6.1 Static demo

Voice and text I/O for Svelte 5

Give your interface a voice.

A Svelte 5 controller for ElevenLabs Conversational AI, with a SvelteKit showcase in this repository. It opens the socket, negotiates the audio format, turns protocol events into reactive state, and releases every browser resource when the session ends.

  • Svelte 5runes · SSR-safe
  • Signed URLskey stays server-side
  • 8 to 48 kHzPCM · AudioWorklet
01 / LOW LATENCY 02 / BARGE-IN READY 03 / CLEAN TEARDOWN 04 / BUN AND NODE MIT

01 Live console

Talk to the machine.

This static build connects with public agent ids. Paste one, press start, and the browser opens the audio line. Signed URLs require the server build.

SEL-01 / Signal console
CH 01 -
PUBLIC
Standby
T+ 00:00
Mic · analyser / 30 fps Agent · wave clock
First audio
-
You / in
-
Agent / out
-
Turns
00
Barge-ins
00
Transcript printer / CH 01
0 entries live · partials supported

The line is quiet. Press start, grant the microphone, and talk.

Agent text may stream in word by word. Corrections replace the same entry.

02 Under the hood

A short path from
click to conversation.

The controller owns the socket, the audio graph, and the teardown. Your component owns the interface.

  1. 01

    Prepare inside the gesture

    Microphone permission and both AudioContexts start in the click handler, avoiding autoplay gates. Then the URL is resolved and the socket opens with the convai subprotocol.

  2. 02

    Stream up

    A worklet captures ~100 ms chunks. They are low-pass filtered, resampled to the negotiated rate, encoded as PCM16 little-endian base64, and sent as user_audio_chunk.

  3. 03

    Schedule down

    Agent chunks are decoded onto one playback clock. Two AnalyserNode instances feed the spectra; local or server barge-in flushes every queued source with a 12 ms gain ramp.

  4. 04

    Leave nothing running

    An $effect teardown closes the socket, stops media tracks, disconnects the graph, revokes worklet URLs, closes both contexts, and clears its timers.

Fig. 01 / Signal path WSS · CONVAI
Signed mode Browser /api/signed-url xi-api-key ElevenLabs
Client-side latency Server-only key

03 Install and start

Five lines to
a first sentence.

Install the package, hand the controller an agent id, and start a session. Public ids work anywhere. Signed mode adds one server route and keeps the key out of the bundle.

01 Install the package
bun add svelte-elevenlabs

Peer dependency: Svelte 5. The library is ESM-only and publishes its TypeScript surface. The package tooling runs on Node 22.17+ or Bun 1.4+.

02 Keep the secret on the server
# .env: never expose this through PUBLIC_*
ELEVENLABS_API_KEY=your_key_here
# optional demo prefill
PUBLIC_ELEVENLABS_AGENT_ID=agent_examplePublicId

The included SvelteKit route reads process.env and returns only a short-lived signed URL.

03 Run it
bun install
bun run dev

Open the console on localhost or HTTPS. Microphone access is blocked in insecure contexts by design.

Quickstart SVELTE 5 / RUNES
<script lang="ts">
  import { useConversation } from 'svelte-elevenlabs';
  const conversation = useConversation({ agentId: 'agent_…' });
</script>
<button onclick={() => conversation.startConversation()}>Talk</button>

Controller fields use Svelte 5 runes: read conversation.status, transcripts, and volume directly in markup.

API map ↓

When using ConversationWidget in your own Tailwind app, add @source '../node_modules/svelte-elevenlabs/dist'; to your stylesheet so utility classes can be discovered. Scoped component styles do not require it.

Using Claude Code, Cursor, OpenCode, Copilot, Windsurf, Cline, or Gemini CLI? Run bunx svelte-elevenlabs agents install to add one reviewed guide to the file your tool already reads, then see the agent kit docs.

04 API map

Small surface.
Deep control.

The core controller exposes the reactive values and lifecycle methods the interface needs, including text only sessions, client tools, feedback, and device control. Everything else is an optional extension.

Controller state Read in markup
status
"disconnected" | "connecting" | "connected"
isSpeaking
Agent playback is scheduled or audible.
isListening
Microphone is live and the agent can hear it.
isTextOnly
The current or next session is text only.
volume
number: combined level, 0 to 1.
transcripts
TranscriptMessage[]: stable streaming entries.
error
string | null: safe to render; code in errorCode.
Methods and helpers Browser lifecycle
startConversation(target?, { signed?, textOnly? })

Opens the mic or text channel and the socket. Accepts a public agent id, signed wss:// URL, or configured default. textOnly overrides the controller default for this session.

stopConversation()

Ends the call, flushes playback, closes audio, and preserves transcripts.

toggleMute()

Stops outgoing chunks without closing the microphone track. Instant undo.

sendContextualUpdate(text)

Injects context for the agent's next turn without interrupting speech.

sendUserMessage(text)

Adds a typed user turn over the same WebSocket.

sendFeedback(like, eventId?)

Submits positive or negative feedback for an agent response.

changeInputDevice(id?)

Switches the microphone while a voice session is active.

changeOutputDevice(id?)

Routes agent playback to another output device.

Included UI

Use the parts, or none of them.

<AudioVisualizer> renders the live analyser data. <ConversationWidget> packages the field controls, transcript, mute, and telemetry. Both accept a controller you already own.

import { AudioVisualizer, ConversationWidget } from 'svelte-elevenlabs';

Component lifecycle. Call useConversation during component initialisation; it registers the cleanup effect. Use createConversation when you need to own teardown yourself.

05 Community file

Built against
the public protocol.

This is an independent library, not an official SDK. It follows the Conversational AI WebSocket protocol, documents its failure modes, and prefers a clear error over a silent dead line.

This is an independent community project. Not affiliated with or endorsed by ElevenLabs Inc.

MIT licensed Runs on Bun and Node Issues welcome Author: AnonymousGCA ↗