@vocobase/voice-client-sdk-rn
v1.0.0
Published
React Native SDK for Vocobase voice AI agents
Maintainers
Readme
@vocobase/voice-client-sdk-rn
React Native SDK for integrating Vocobase voice AI agents into iOS and Android applications.
Requirements
| Platform | Minimum Version | |----------|-----------------| | iOS | 15.0+ | | Android | SDK 24+ (Android 7.0) | | React Native | 0.70.0+ | | React | 18.0.0+ | | Expo | SDK 50+ (if using Expo) |
Important: This SDK uses native modules (WebRTC) and cannot run in Expo Go. You must use a development build.
Installation
Step 1: Handle Peer Dependency Conflicts
Before installing, create a .npmrc file in your project root to avoid ERESOLVE errors:
legacy-peer-deps=trueStep 2: Install the SDK and Dependencies
For Expo projects:
# Install the SDK
npm install @vocobase/voice-client-sdk-rn
# Install required peer dependencies
npx expo install @daily-co/react-native-daily-js @daily-co/react-native-webrtc
npx expo install @pipecat-ai/client-js @pipecat-ai/react-native-daily-transport
npx expo install @react-native-async-storage/async-storage
npx expo install @react-native-community/netinfo
npx expo install react-native-background-timer react-native-get-random-values
npx expo install react-native-url-polyfill base-64
# For permission handling (recommended)
npx expo install expo-camera expo-avFor bare React Native projects:
npm install @vocobase/voice-client-sdk-rn
npm install @daily-co/react-native-daily-js @daily-co/react-native-webrtc
npm install @pipecat-ai/client-js @pipecat-ai/react-native-daily-transport
npm install @react-native-async-storage/async-storage
npm install @react-native-community/netinfo
npm install react-native-background-timer react-native-get-random-values
npm install react-native-url-polyfill base-64
cd ios && pod installStep 3: Configure Platform Permissions
iOS (Expo)
Add to app.json:
{
"expo": {
"ios": {
"bundleIdentifier": "com.yourcompany.yourapp",
"infoPlist": {
"NSMicrophoneUsageDescription": "This app needs microphone access for voice conversations.",
"NSCameraUsageDescription": "This app may use camera for video calls."
}
}
}
}Note: Camera permission is required by Daily.co WebRTC even for audio-only calls. Without it, the app will crash when starting a call.
iOS (Bare React Native)
Add to ios/YourApp/Info.plist:
<key>NSMicrophoneUsageDescription</key>
<string>This app needs microphone access for voice conversations.</string>
<key>NSCameraUsageDescription</key>
<string>This app may use camera for video calls.</string>Android (Expo)
Add to app.json:
{
"expo": {
"android": {
"package": "com.yourcompany.yourapp",
"permissions": [
"RECORD_AUDIO",
"CAMERA",
"INTERNET",
"MODIFY_AUDIO_SETTINGS"
]
}
}
}Android (Bare React Native)
Add to android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />Step 4: Build Development Build (Expo)
# Clean and regenerate native projects
npx expo prebuild --clean
# Build and run
npx expo run:ios # iOS
npx expo run:android # AndroidRequesting Permissions Early (Recommended)
For better UX, request permissions when your app loads, not when starting a call:
import { useEffect, useState } from 'react'
import { Alert } from 'react-native'
import { Camera } from 'expo-camera'
import { Audio } from 'expo-av'
function usePermissions() {
const [granted, setGranted] = useState(false)
useEffect(() => {
async function request() {
const { status: cam } = await Camera.requestCameraPermissionsAsync()
const { status: mic } = await Audio.requestPermissionsAsync()
if (cam === 'granted' && mic === 'granted') {
setGranted(true)
} else {
Alert.alert('Permissions Required', 'Enable camera & microphone in Settings')
}
}
request()
}, [])
return granted
}Quick Start
import {
VoiceSessionProvider,
useVoiceSession,
useConnectionState,
useTranscript,
} from '@vocobase/voice-client-sdk-rn'
function App() {
return (
<VoiceSessionProvider
apiKey="rg_live_your_api_key"
agentName="my-agent"
onError={(error) => console.error(error)}
>
<VoiceScreen />
</VoiceSessionProvider>
)
}
function VoiceScreen() {
const { connect, disconnect } = useVoiceSession()
const { isConnected, isConnecting } = useConnectionState()
const { entries } = useTranscript()
return (
<View>
{!isConnected ? (
<Button
title={isConnecting ? 'Connecting...' : 'Start Call'}
onPress={connect}
disabled={isConnecting}
/>
) : (
<>
<FlatList
data={entries}
renderItem={({ item }) => (
<Text>{item.role}: {item.content}</Text>
)}
/>
<Button title="End Call" onPress={disconnect} />
</>
)}
</View>
)
}Hooks
useVoiceSession
const { connect, disconnect, sessionId, error } = useVoiceSession()useConnectionState
const {
state, // 'idle' | 'connecting' | 'connected' | 'reconnecting' | 'disconnecting' | 'disconnected' | 'error'
isConnected,
isConnecting,
isReconnecting,
isDisconnected,
reconnectAttempt,
maxReconnectAttempts,
} = useConnectionState()useTranscript
const {
entries, // TranscriptEntry[]
latestEntry, // TranscriptEntry | null
count, // number
isEmpty, // boolean
} = useTranscript()useAudioLevel
const {
userLevel, // 0-1 audio level from user's mic
botLevel, // 0-1 audio level from bot's response
} = useAudioLevel()useNetworkStatus
const { isOnline, lastChanged } = useNetworkStatus()Components
AudioLevelIndicator
import { AudioLevelIndicator } from '@vocobase/voice-client-sdk-rn'
<AudioLevelIndicator
type="user" // 'user' | 'bot'
barCount={5}
barWidth={4}
barGap={2}
maxHeight={40}
activeColor="#007AFF"
inactiveColor="#E5E5E5"
/>ConnectionButton
import { ConnectionButton } from '@vocobase/voice-client-sdk-rn'
<ConnectionButton
variant="connect"
isLoading={isConnecting}
onPress={connect}
style={styles.button}
>
<Text>Start Conversation</Text>
</ConnectionButton>Provider Props
interface VoiceSessionProviderProps {
apiKey: string
agentName: string
children: ReactNode
onConnect?: () => void
onDisconnect?: () => void
onError?: (error: VoiceAgentError) => void
onTranscript?: (entry: TranscriptEntry) => void
onSessionEnd?: (data: SessionEndData) => void
onReconnecting?: (attempt: number, maxAttempts: number) => void
onReconnected?: () => void
maxReconnectAttempts?: number // Default: 3
}Configuration
import { setConfig, resetConfig } from '@vocobase/voice-client-sdk-rn'
setConfig({
baseUrl: 'https://api.vocobase.com',
retry: { maxAttempts: 3, baseDelayMs: 1000, maxDelayMs: 10000 },
connection: { timeoutMs: 30000, reconnectAttempts: 3 },
transcript: { maxEntries: 100 },
debug: true,
})Troubleshooting
ERESOLVE unable to resolve dependency tree
Create .npmrc in project root:
legacy-peer-deps=trueUnable to resolve module react-native-background-timer
npm install react-native-background-timer react-native-url-polyfill base-64 --legacy-peer-depsTurboModuleRegistry.getEnforcing(...): 'PlatformConstants' could not be found
Install Pipecat packages in your app:
npx expo install @pipecat-ai/client-js @pipecat-ai/react-native-daily-transportApp crashes when starting a call (iOS)
Error: NSCameraUsageDescription key missing
Add camera permission to app.json:
{
"expo": {
"ios": {
"infoPlist": {
"NSCameraUsageDescription": "This app may use camera for video calls."
}
}
}
}Then rebuild: npx expo prebuild --clean && npx expo run:ios
"Expo Go is not supported"
This SDK requires a development build:
npx expo prebuild --clean
npx expo run:iosTypeScript
import type {
ConnectionState,
VoiceAgentError,
VoiceAgentErrorCode,
TranscriptEntry,
SessionEndData,
} from '@vocobase/voice-client-sdk-rn'License
MIT
