@tundra-audio/react-native
v0.8.5
Published
Real-time voice call native library for Expo
Downloads
1,193
Readme
@tundra-audio/react-native
Real-time voice AI for Expo apps. Native audio engine (record + playback), WebSocket streaming, and ready-to-use React hooks for continuous voice calls and push-to-talk conversations.
- 🎙️ Native iOS/Android audio capture and playback (PCM16)
- 🔌 Built-in WebSocket client with backpressure-aware streaming
- 🪝 Drop-in
useVoiceCallanduseVoicePtthooks - 🔐 Signed-URL / JWT auth flow baked in
- ⚡ Barge-in support — interrupt the agent mid-sentence
Installation
npx expo install @tundra-audio/react-nativeThen add the config plugin to your app.json / app.config.ts:
{
"expo": {
"plugins": ["@tundra-audio/react-native"]
}
}Rebuild the dev client (expo prebuild + native rebuild) — this package ships native code.
Quick start
Continuous voice call
import { useVoiceCall } from '@tundra-audio/react-native';
const { status, micStatus, speakerStatus, initialize, end } = useVoiceCall({
agentId: 'YOUR_AGENT_UUID',
getSignedUrl: async () => {
// fetch a short-lived signed WSS URL from your backend
const res = await fetch('https://your-api/voice/signed-url');
return (await res.json()).url;
},
});
await initialize(); // start the call
await end(); // hang upPush-to-talk
import { useVoicePtt } from '@tundra-audio/react-native';
const { status, startRecording, stopRecording, transcript, assistantText } =
useVoicePtt({
agentId: 'YOUR_AGENT_UUID',
getToken: async () => {
// return a JWT for the voice backend
const res = await fetch('https://your-api/voice/token');
return (await res.json()).token;
},
});API
useVoiceCall(options)
Continuous WebSocket voice call. Manages permissions, handshake, recording, and playback.
| Option | Type | Description |
|---|---|---|
| agentId | string? | Agent UUID. Used to construct the fallback WS URL. |
| getSignedUrl | () => Promise<string>? | Returns a fully signed WSS URL (with auth token). |
| baseUrl | string? | Override base URL for dev/testing. Defaults to production. |
Returns: { status, micStatus, speakerStatus, lastFrame, initialize, end, startMic, stopMic }.
status is one of 'idle' | 'initializing' | 'listening' | 'thinking' | 'speaking'.
useVoicePtt(options)
HTTP-based push-to-talk. Records an utterance, uploads it, and plays back the response. Token caching (9 min) and refresh are handled internally.
| Option | Type | Description |
|---|---|---|
| agentId | string | Agent UUID. |
| getToken | () => Promise<string> | Returns a JWT for the voice backend. |
| baseUrl | string? | Override base URL for dev/testing. |
| locale | string? | On-device ASR locale. Default 'pt-BR'. |
| logLevel | 'debug' \| 'info' \| 'warn' \| 'error'? | Log verbosity. Default 'info'. |
| initialSessionId | string? | Resume a previous conversation. |
| overrides.firstMessage | string? | Hidden trigger so the agent speaks first. |
| clientData | Record<string, unknown>? | Session-scoped metadata injected into the system prompt. |
tundraAudio
Native module — direct access to the audio engine. Used internally by both hooks.
import { tundraAudio } from '@tundra-audio/react-native';
await tundraAudio.initialize({ playbackSampleRate: 24000, frameDurationMs: 50 });
await tundraAudio.startRecording({ frameDurationMs: 50 });
tundraAudio.feedBytes(base64Pcm16);
await tundraAudio.stopRecording();
await tundraAudio.cleanup();webSocketService
Singleton WebSocket client. Used internally by useVoiceCall.
import { webSocketService } from '@tundra-audio/react-native';
webSocketService.connect(url);
webSocketService.sendMessage({ type: 'start', recording_sample_rate: 16000 });
webSocketService.disconnect();Permission helpers
import {
checkMicPermission,
requestMicPermission,
checkSpeechPermission,
requestSpeechPermission,
} from '@tundra-audio/react-native';Auth
Never put your voice backend API key on the client. Have your own backend mint a signed URL (for useVoiceCall) or a short-lived JWT (for useVoicePtt) and return it from getSignedUrl / getToken.
Requirements
- Expo SDK ≥ 50
- React ≥ 18
- React Native ≥ 0.73
- iOS 13+ / Android API 24+
License
MIT
