Avatoon is a lightweight React Three Fiber component for rendering animated 3D avatars with real-time viseme-driven lip-sync. It supports lifelike head movements, morph target control, and optional goal-based gestures (e.g., flexing, sleeping), making it ideal for voice assistants, interactive characters, or storytelling apps.
- 🎤 Real-time lip-sync using phoneme-viseme mapping
- 🧍 Subtle head motion animation while talking
- 🌐 GLTF model support via
useGLTF
- ⚛️ Plug-and-play with React Three Fiber + Drei
- 🎯 Goal-based gestures like "Muscle" or "Sleep"
npm install avatoon
import { Avatoon } from "avatoon";
export default App = () => {
const visemeJson = {
visemes: [{
{ "time": 0, "viseme": "X" },
{ "time": 1.3, "viseme": "A" },
{ "time": 1.367, "viseme": "C" },
}],
audio_base64: '',
};
return (
<Avatoon
glbUrl='https://raw.githubusercontent.com/khaledalam/avatoon/main/test/assets/placeholder-avatar.glb'
goal={"Normal"}
onRenderComplete={() => console.log("Render Completed!")}
visemeJson={visemeJson}
/>
);
}
npm run example
Prop | Type | Default | Description |
---|---|---|---|
glbUrl |
string |
(required) | URL to the .glb avatar file (T1 or T2) |
goal |
string |
"Normal" |
Goal-based motion preset: "Muscle" , "Sleep" , etc. |
onRenderComplete |
() => void |
undefined |
Callback fired when avatar finishes rendering |
visemeJson |
VisemeData |
undefined |
JSON structure for syncing visemes with audio playback |
showPlayVoiceButton |
boolean |
false |
If true, renders a play/stop voice button in the scene |
- T1 (Static Face - Realistic)
- T2 (Blendshape Face - Expressive)
interface VisemeData {
visemes: Array<{ time: number; viseme: string | null }>;
audio_base64?: string;
}
Pull requests are welcome! If you'd like to suggest improvements or fix issues, feel free to fork and submit.
Khaled Alam
📧 khaledalam.net@gmail.com
🌍 Website | LinkedIn | X(Twitter)