> ## Documentation Index
> Fetch the complete documentation index at: https://docs.talking-avatar.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Install the open-source SDK and make your 3D avatar talk.

## Install

```bash npm theme={null}
npm install @interviewflowai/talking-avatar three
```

```bash pnpm theme={null}
pnpm add @interviewflowai/talking-avatar three
```

```bash yarn theme={null}
yarn add @interviewflowai/talking-avatar three
```

`three` (version 0.160 or later) renders the 3D avatar. React (18 or later) is only needed for the [React component](#react). The package is ESM-only.

## JavaScript

```html theme={null}
<div id="avatar" style="width: 640px; height: 360px"></div>
<button id="start">Start</button>
```

```js theme={null}
import { TalkingAvatar } from "@interviewflowai/talking-avatar";

const avatar = new TalkingAvatar({
  container: document.getElementById("avatar"),
  avatarUrl: "https://example.com/avatar.glb", // any .glb with Oculus visemes
});

document.getElementById("start").onclick = () => {
  avatar.speak("/hello.mp3");          // a clip…
  // avatar.attachStream(mediaStream); // …or live audio
};
```

The avatar plays the audio itself, in sync with its mouth. Don't play the same audio anywhere else.

> [!WARNING]
>
> Browsers only allow sound after the user has interacted with the page. Call `speak` or `attachStream` from a click (or after one), or the audio, and with it the lip sync, stays silent.

## React

```jsx theme={null}
"use client"; // needed in the Next.js App Router
import { useRef } from "react";
import { TalkingAvatarView } from "@interviewflowai/talking-avatar/react";

export function Agent({ stream }) {
  const avatar = useRef(null); // the TalkingAvatar instance

  return (
    <div style={{ width: 640, height: 360 }}>
      <TalkingAvatarView ref={avatar} avatarUrl="https://example.com/avatar.glb" stream={stream} />
      <button onClick={() => avatar.current?.speak("/hello.mp3")}>Say hello</button>
    </div>
  );
}
```

Passing `stream={null}` detaches the stream. Changing `avatarUrl` swaps the avatar without recreating anything. The component cleans up when it unmounts. See the [React reference](https://docs.talking-avatar.dev/sdk/react.md).

## Without a bundler

Use an import map:

```html theme={null}
<script type="importmap">
  {
    "imports": {
      "three": "https://cdn.jsdelivr.net/npm/three@0.186.0/build/three.module.js",
      "three/examples/jsm/": "https://cdn.jsdelivr.net/npm/three@0.186.0/examples/jsm/",
      "@interviewflowai/talking-avatar": "https://cdn.jsdelivr.net/npm/@interviewflowai/talking-avatar@0.2.0/dist/index.js"
    }
  }
</script>
<script type="module">
  import { TalkingAvatar } from "@interviewflowai/talking-avatar";
</script>
```

## Clean up

```js theme={null}
avatar.dispose(); // releases the canvas, WebGL resources and audio; the instance can't be reused
```

## Need an avatar?

Your avatar must be a `.glb` with the Oculus viseme morph targets. See [Avatars](https://docs.talking-avatar.dev/open-source/avatars.md) for the requirements, and how to map other morph names.

## Next steps

> **[Audio sources](https://docs.talking-avatar.dev/open-source/audio-sources.md)**
>
> Clips, live streams, and voice agents on OpenAI Realtime, LiveKit or Daily.

> **[API reference](https://docs.talking-avatar.dev/sdk/talking-avatar.md)**
>
> Every option and method of `TalkingAvatar`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.