npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@octaiv/sdk

v1.0.3

Published

Official Octaiv SDK - Universal avatar components with AI voice interaction for React, Vue, Angular, Svelte, and vanilla JavaScript. Easy integration, powerful features.

Readme

@octaiv/sdk

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.

🌟 Features

  • 🎭 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)

📦 Installation

Quick Install (if you already have React)

npm install @octaiv/sdk

Full Install (if you need React too)

npm install react react-dom @octaiv/sdk

What's Included

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)

🚀 Quick Start

Basic Avatar (No Voice)

import { Octaiv } from '@octaiv/sdk';

function App() {
  return (
    <div style={{ width: '100vw', height: '100vh' }}>
      <Octaiv 
        config={{
          modelUrl: '/path/to/your/avatar.glb'
        }}
      />
    </div>
  );
}

Avatar with Voice Interaction

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>
  );
}

📋 Required Inputs

Essential Requirements

| Input | Type | Required | Description | |-------|------|----------|-------------| | config.modelUrl | string | ✅ Yes | Path to your GLB/GLTF 3D model file |

Voice Requirements (if using voice features)

| 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 |

🔧 Framework Compatibility

Currently Supported

  • 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*

🌐 Universal Standalone Version

  • 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

🚧 Coming Soon

  • Native Vue Components - Planned
  • Native Angular Components - Planned

📞 Need Another Framework?

Contact us at [email protected] to request support for your framework.

*React Native support requires additional native dependencies for 3D rendering.

🌐 Using with Non-React Frameworks

Standalone Bundle (Any Framework)

For Vue, Angular, Svelte, or Vanilla JavaScript, use the standalone bundle:

<!-- Load dependencies -->
<script src="https://unpkg.com/[email protected]/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>

Vue.js Example

<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>

Angular Example

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();
    }
  }
}

🎛 Environment Setup

Environment Variables

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

Getting Your API Credentials

  1. Sign up for Octaiv: Visit octaiv.com and create an account
  2. Get your API Key: Found in your Octaiv dashboard
  3. Create an Assistant: Set up your AI assistant and get the Assistant ID
  4. Configure Voice Settings: Set up voice, language, and behavior preferences

✅ Integration Checklist

Before implementing Octaiv in your project, ensure you have:

🎯 3D Model Requirements

  • [ ] GLB or GLTF format model file
  • [ ] Model includes mouthOpen morph target (required for voice animation)
  • [ ] Model includes eyeBlinkLeft and eyeBlinkRight morph targets (optional)
  • [ ] File size under 10MB for web performance
  • [ ] Triangle count under 50,000 for optimal performance

🔑 API Configuration

  • [ ] Valid Octaiv API key
  • [ ] Created AI assistant with Assistant ID
  • [ ] Environment variables properly configured
  • [ ] Voice features enabled in your assistant settings

🌐 Framework Setup

  • [ ] React 16.8+ installed (for React components)
  • [ ] Three.js dependencies installed automatically
  • [ ] Container element with defined width/height
  • [ ] HTTPS enabled (required for microphone access)

🎤 Voice Integration Testing

  • [ ] 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

🔧 Troubleshooting Tools

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;
}

📖 Basic Usage Examples

1. Custom Avatar Positioning

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>
  );
}

2. Voice Integration with Event Handling

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>
  );
}

3. Custom Controls with Hooks

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>
  );
}

🎤 Starting Voice Conversations

Users can initiate voice conversations in several ways:

Built-in Controls (Easiest)

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>
  );
}

Custom Button

const { toggleCall, isSessionActive, isConnecting } = useOctaivVoice(voiceConfig);

<button 
  onClick={toggleCall}
  disabled={isConnecting}
>
  {isConnecting ? 'Connecting...' : 
   isSessionActive ? 'End Call' : 'Start Voice Chat'}
</button>

Event-Triggered Calls

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>

🎯 3D Model Requirements

File Format

  • Supported: GLB, GLTF
  • Recommended: GLB (binary format for better performance)

Required Morph Targets

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 |

Model Optimization Tips

  • Polygon Count: Keep under 50k triangles for web performance
  • Texture Size: Use 1024x1024 or 2048x2048 textures
  • Compression: Use Draco compression for smaller file sizes

📱 Responsive Design

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>
  );
}

🚨 Common Issues and Solutions

Model Loading Errors

  • Ensure your GLB/GLTF file is accessible from the public directory
  • Check browser console for specific loading errors
  • Verify file format and compression

Voice Connection Issues

  • Verify your API key and assistant ID are correct
  • Check that environment variables are properly loaded
  • Ensure voice features are enabled in your configuration

Performance Issues

  • Optimize your 3D model (reduce polygons, compress textures)
  • Use React.memo for static configurations
  • Implement proper cleanup in useEffect hooks

🎯 Performance Tips

  1. Model Optimization: Use compressed GLB files with optimized textures
  2. Component Optimization: Use React.memo for static configurations
  3. Voice Optimization: Only enable voice when needed, handle errors gracefully

Powered by Octaiv - Bringing AI avatars to life 🚀