The official Octaiv SDK - Universal avatar components with built-in AI voice interaction support. Works with React, Vue, Angular, Svelte, and vanilla JavaScript. Built with React Three Fiber and advanced voice AI technology.
🌐 Universal SDK: This package works with any JavaScript framework. Use React components for React apps, or the standalone bundle for Vue, Angular, Svelte, and vanilla JavaScript.
- 🎭 High-Quality 3D Rendering: Smooth 3D avatar models with realistic animations
- 🗣️ AI Voice Integration: Built-in conversational AI with natural voice interaction
- 🎨 Fully Configurable: Customize every aspect - position, lighting, camera, animations
- 📱 Responsive Design: Works seamlessly across devices and screen sizes
- 🔧 TypeScript First: Complete type safety with full TypeScript definitions
- ⚡ Performance Optimized: Efficient rendering with React Three Fiber
- 🎯 Easy Integration: Simple API for quick setup in any React app
- 🌐 Universal Compatibility: React components + standalone bundle for any framework
- ⚛️ React Native Compatible: Works with React Native (with additional setup)
npm install @octaiv/sdk
npm install react react-dom @octaiv/sdk
✅ Automatically installed with @octaiv/sdk:
-
@react-three/fiber
- React Three.js renderer -
@react-three/drei
- Useful Three.js helpers -
three
- Three.js 3D library - Voice AI integration library
❌ Required peer dependencies (install separately):
-
react
(>=16.8.0) -
react-dom
(>=16.8.0)
import { Octaiv } from '@octaiv/sdk';
function App() {
return (
<div style={{ width: '100vw', height: '100vh' }}>
<Octaiv
config={{
modelUrl: '/path/to/your/avatar.glb'
}}
/>
</div>
);
}
import { Octaiv } from '@octaiv/sdk';
function VoiceApp() {
return (
<div style={{ width: '100vw', height: '100vh' }}>
<Octaiv
config={{
modelUrl: '/avatar.glb'
}}
voiceConfig={{
apiKey: 'your-octaiv-api-key',
assistantId: 'your-assistant-id',
enabled: true
}}
/>
</div>
);
}
Input | Type | Required | Description |
---|---|---|---|
config.modelUrl |
string |
✅ Yes | Path to your GLB/GLTF 3D model file |
Input | Type | Required | Description |
---|---|---|---|
voiceConfig.apiKey |
string |
✅ Yes | Your Octaiv API key |
voiceConfig.assistantId |
string |
✅ Yes | Your AI assistant ID |
voiceConfig.enabled |
boolean |
✅ Yes | Set to true to enable voice |
- React (16.8+) - Full support with React components
- Next.js - Full support
- Vite + React - Full support
- Create React App - Full support
- React Native - Experimental support*
- Vanilla JavaScript - Full support via standalone bundle
- Vue.js - Full support via standalone bundle
- Angular - Full support via standalone bundle
- Svelte - Full support via standalone bundle
- Any Framework - Works with any JavaScript framework
- Native Vue Components - Planned
- Native Angular Components - Planned
Contact us at support@octaiv.com to request support for your framework.
*React Native support requires additional native dependencies for 3D rendering.
For Vue, Angular, Svelte, or Vanilla JavaScript, use the standalone bundle:
<!-- Load dependencies -->
<script src="https://unpkg.com/three@0.166.1/build/three.min.js"></script>
<script src="https://unpkg.com/@octaiv/sdk/dist/octaiv-standalone.min.js"></script>
<script>
// Create avatar instance
const avatar = Octaiv.create({
container: document.getElementById('avatar-container'),
modelUrl: '/models/avatar.glb'
}, {
apiKey: 'your-octaiv-api-key',
assistantId: 'your-assistant-id',
enabled: true
});
// Control the avatar
avatar.startVoiceSession();
avatar.updatePosition([0, -1, 0]);
avatar.setMouthOpen(0.5);
</script>
<template>
<div>
<div ref="avatarContainer" class="avatar-container"></div>
<button @click="toggleVoice">{{ isVoiceActive ? 'End Call' : 'Start Voice' }}</button>
</div>
</template>
<script>
import { Octaiv } from '@octaiv/sdk/standalone';
export default {
data() {
return {
avatar: null,
isVoiceActive: false
}
},
mounted() {
this.avatar = Octaiv.create({
container: this.$refs.avatarContainer,
modelUrl: '/models/avatar.glb'
});
},
methods: {
async toggleVoice() {
if (this.isVoiceActive) {
this.avatar.endVoiceSession();
} else {
await this.avatar.startVoiceSession();
}
this.isVoiceActive = this.avatar.isVoiceActive();
}
},
beforeUnmount() {
if (this.avatar) {
this.avatar.destroy();
}
}
}
</script>
import { Component, ElementRef, ViewChild, OnInit, OnDestroy } from '@angular/core';
import { Octaiv } from '@octaiv/sdk/standalone';
@Component({
selector: 'app-avatar',
template: `
<div #avatarContainer class="avatar-container"></div>
<button (click)="toggleVoice()">{{ isVoiceActive ? 'End Call' : 'Start Voice' }}</button>
`
})
export class AvatarComponent implements OnInit, OnDestroy {
@ViewChild('avatarContainer', { static: true }) avatarContainer!: ElementRef;
private avatar: any;
public isVoiceActive = false;
ngOnInit() {
this.avatar = Octaiv.create({
container: this.avatarContainer.nativeElement,
modelUrl: '/assets/models/avatar.glb'
});
}
async toggleVoice() {
if (this.isVoiceActive) {
this.avatar.endVoiceSession();
} else {
await this.avatar.startVoiceSession();
}
this.isVoiceActive = this.avatar.isVoiceActive();
}
ngOnDestroy() {
if (this.avatar) {
this.avatar.destroy();
}
}
}
Create a .env.local
file in your project root:
# Octaiv Configuration
NEXT_PUBLIC_OCTAIV_API_KEY=your_octaiv_api_key_here
NEXT_PUBLIC_OCTAIV_ASSISTANT_ID=your_assistant_id_here
# Optional: Custom model paths
NEXT_PUBLIC_AVATAR_MODEL_URL=/models/avatar.glb
- Sign up for Octaiv: Visit octaiv.com and create an account
- Get your API Key: Found in your Octaiv dashboard
- Create an Assistant: Set up your AI assistant and get the Assistant ID
- Configure Voice Settings: Set up voice, language, and behavior preferences
Before implementing Octaiv in your project, ensure you have:
- [ ] GLB or GLTF format model file
- [ ] Model includes
mouthOpen
morph target (required for voice animation) - [ ] Model includes
eyeBlinkLeft
andeyeBlinkRight
morph targets (optional) - [ ] File size under 10MB for web performance
- [ ] Triangle count under 50,000 for optimal performance
- [ ] Valid Octaiv API key
- [ ] Created AI assistant with Assistant ID
- [ ] Environment variables properly configured
- [ ] Voice features enabled in your assistant settings
- [ ] React 16.8+ installed (for React components)
- [ ] Three.js dependencies installed automatically
- [ ] Container element with defined width/height
- [ ] HTTPS enabled (required for microphone access)
- [ ] Microphone permissions granted in browser
- [ ] Voice session starts without errors
- [ ] Volume level events firing during speech
- [ ] Mouth animation responds to voice volume
- [ ] Assistant speech pauses main character animation
Use this code snippet to verify your setup:
import { useEffect } from 'react';
import { useGLTF } from '@react-three/drei';
function IntegrationTester() {
const { scene } = useGLTF('/models/avatar.glb');
useEffect(() => {
// Check model morph targets
scene.traverse((child: any) => {
if (child.isMesh && child.morphTargetDictionary) {
const morphs = Object.keys(child.morphTargetDictionary);
console.log('✅ Available morph targets:', morphs);
if (morphs.includes('mouthOpen')) {
console.log('✅ Required mouthOpen morph target found');
} else {
console.error('❌ Missing required mouthOpen morph target');
}
}
});
// Check environment variables
const apiKey = process.env.NEXT_PUBLIC_OCTAIV_API_KEY;
const assistantId = process.env.NEXT_PUBLIC_OCTAIV_ASSISTANT_ID;
if (apiKey) {
console.log('✅ API key configured');
} else {
console.error('❌ Missing NEXT_PUBLIC_OCTAIV_API_KEY');
}
if (assistantId) {
console.log('✅ Assistant ID configured');
} else {
console.error('❌ Missing NEXT_PUBLIC_OCTAIV_ASSISTANT_ID');
}
}, [scene]);
return null;
}
import { Octaiv } from '@octaiv/sdk';
function CustomPositionExample() {
const config = {
modelUrl: '/models/avatar.glb',
position: [0, -1.5, 0], // Move avatar down
scale: 1.2, // Make avatar 20% larger
camera: {
position: [-3, 0.5, 4], // Move camera back and up
fov: 15 // Narrow field of view
}
};
return (
<div style={{ width: '800px', height: '600px' }}>
<Octaiv config={config} />
</div>
);
}
import { Octaiv } from '@octaiv/sdk';
function VoiceExample() {
const avatarConfig = {
modelUrl: '/models/avatar.glb',
position: [0, -1.6, 0],
scale: 1.1
};
const voiceConfig = {
apiKey: process.env.NEXT_PUBLIC_OCTAIV_API_KEY!,
assistantId: process.env.NEXT_PUBLIC_OCTAIV_ASSISTANT_ID!,
enabled: true
};
const handleVoiceStart = () => {
console.log('🎤 Voice session started');
};
const handleVoiceEnd = () => {
console.log('🔇 Voice session ended');
};
const handleVoiceError = (error: string) => {
console.error('❌ Voice error:', error);
alert(`Voice Error: ${error}`);
};
return (
<div style={{ width: '100%', height: '100vh' }}>
<Octaiv
config={avatarConfig}
voiceConfig={voiceConfig}
onVoiceSessionStart={handleVoiceStart}
onVoiceSessionEnd={handleVoiceEnd}
onVoiceError={handleVoiceError}
style={{ border: '2px solid #ccc' }}
className="avatar-container"
/>
</div>
);
}
import { Octaiv, OctaivControls, useOctaivVoice } from '@octaiv/sdk';
function CustomControlsExample() {
const voiceConfig = {
apiKey: process.env.NEXT_PUBLIC_OCTAIV_API_KEY!,
assistantId: process.env.NEXT_PUBLIC_OCTAIV_ASSISTANT_ID!,
enabled: true
};
const {
isSessionActive,
isConnecting,
toggleCall,
error,
conversation,
volumeLevel
} = useOctaivVoice(voiceConfig);
return (
<div>
{/* Avatar Display */}
<div style={{ width: '100%', height: '500px', marginBottom: '20px' }}>
<Octaiv
config={{ modelUrl: '/models/avatar.glb' }}
voiceConfig={voiceConfig}
/>
</div>
{/* Custom Controls */}
<div style={{ textAlign: 'center', padding: '20px' }}>
<OctaivControls
isSessionActive={isSessionActive}
isConnecting={isConnecting}
onToggleCall={toggleCall}
startText="🎤 Talk to Octaiv"
endText="🔇 End Conversation"
connectingText="🔄 Connecting..."
buttonStyle={{
backgroundColor: isSessionActive ? '#ef4444' : '#10b981',
color: 'white',
padding: '15px 30px',
fontSize: '18px',
borderRadius: '10px',
border: 'none',
cursor: 'pointer'
}}
/>
{/* Status Display */}
<div style={{ marginTop: '20px' }}>
<p>Status: {isSessionActive ? '🟢 Active' : '🔴 Inactive'}</p>
<p>Volume: {(volumeLevel * 100).toFixed(0)}%</p>
{error && <p style={{ color: 'red' }}>Error: {error}</p>}
</div>
</div>
</div>
);
}
Users can initiate voice conversations in several ways:
import { Octaiv, OctaivControls, useOctaivVoice } from '@octaiv/sdk';
function MyApp() {
const voiceConfig = {
apiKey: process.env.NEXT_PUBLIC_OCTAIV_API_KEY!,
assistantId: process.env.NEXT_PUBLIC_OCTAIV_ASSISTANT_ID!,
enabled: true
};
const { isSessionActive, isConnecting, toggleCall } = useOctaivVoice(voiceConfig);
return (
<div>
<Octaiv
config={{ modelUrl: '/avatar.glb' }}
voiceConfig={voiceConfig}
/>
<OctaivControls
isSessionActive={isSessionActive}
isConnecting={isConnecting}
onToggleCall={toggleCall}
startText="🎤 Talk to Assistant"
endText="🔇 End Call"
/>
</div>
);
}
const { toggleCall, isSessionActive, isConnecting } = useOctaivVoice(voiceConfig);
<button
onClick={toggleCall}
disabled={isConnecting}
>
{isConnecting ? 'Connecting...' :
isSessionActive ? 'End Call' : 'Start Voice Chat'}
</button>
const handleAvatarClick = () => {
if (!isSessionActive) {
toggleCall(); // Start call when avatar is clicked
}
};
<div onClick={handleAvatarClick} style={{ cursor: 'pointer' }}>
<Octaiv config={{ modelUrl: '/avatar.glb' }} voiceConfig={voiceConfig} />
<p>Click the avatar to start talking!</p>
</div>
- Supported: GLB, GLTF
- Recommended: GLB (binary format for better performance)
For facial animations to work properly, your model should include:
Morph Target | Purpose | Default Name |
---|---|---|
Mouth Open | Lip sync animation | mouthOpen |
Left Eye Blink | Eye blinking | eyeBlinkLeft |
Right Eye Blink | Eye blinking | eyeBlinkRight |
- Polygon Count: Keep under 50k triangles for web performance
- Texture Size: Use 1024x1024 or 2048x2048 textures
- Compression: Use Draco compression for smaller file sizes
import { Octaiv } from '@octaiv/sdk';
import { useState, useEffect } from 'react';
function ResponsiveAvatar() {
const [isMobile, setIsMobile] = useState(false);
useEffect(() => {
setIsMobile(window.innerWidth < 768);
}, []);
const config = {
modelUrl: '/models/avatar.glb',
camera: {
position: isMobile ? [-1.5, 0.2, 2.5] : [-2, 0.2, 3],
fov: isMobile ? 20 : 10
},
scale: isMobile ? 0.8 : 1
};
return (
<div style={{
width: '100%',
height: isMobile ? '300px' : '500px'
}}>
<Octaiv config={config} />
</div>
);
}
- Ensure your GLB/GLTF file is accessible from the public directory
- Check browser console for specific loading errors
- Verify file format and compression
- Verify your API key and assistant ID are correct
- Check that environment variables are properly loaded
- Ensure voice features are enabled in your configuration
- Optimize your 3D model (reduce polygons, compress textures)
- Use React.memo for static configurations
- Implement proper cleanup in useEffect hooks
- Model Optimization: Use compressed GLB files with optimized textures
- Component Optimization: Use React.memo for static configurations
- Voice Optimization: Only enable voice when needed, handle errors gracefully
Powered by Octaiv - Bringing AI avatars to life 🚀