React Native SDK

ElevenAgents SDK:React Nativeアプリ向けに、カスタマイズ可能なインタラクティブ音声エージェントを数分で導入。

ElevenAgentsの仕組みについては、ElevenAgentsの概要を参照してください。

インストール

React Nativeプロジェクトにパッケージとその依存関係をインストールします。

npm install @elevenlabs/react-native @livekit/react-native @livekit/react-native-webrtc livekit-client

ExpoでこのSDKを使用するサンプルアプリは、 こちらにあります。

以前のバージョンからアップグレードしますか?npx skills add elevenlabs/packagesを実行すると、 AIコーディングエージェント向けのelevenlabs:sdk-migrationスキルがインストールされ、importの変更、 ConversationProviderのラップ、APIの更新が自動化されます。

要件

  • LiveKitの依存関係を含むReact Native
  • プラットフォームに合わせて設定されたマイク権限
  • Expo互換性(開発ビルドのみ)
  • React Native 0.79.0以降、または旧バージョンではMetroを設定してpackage.jsonの"exports"を解決

このSDKはExpoフレームワークでの利用を想定して設計・開発されています。LiveKitのWebRTC実装に依存するため、 開発ビルドが必要であり、Expo Goでは使用できません。

@elevenlabs/react-nativeは、package.jsonの "exports"フィールドを介してReact Nativeのエントリポイントを解決します。Metroが デフォルトで"exports"を解決するのは、React Native 0.79.0(2025年4月8日リリース)に含まれるMetro 0.82.0以降です。React Nativeが 0.79より古い場合は、このパッケージを正しく解決できるよう、metro.config.jsでresolver.unstable_enablePackageExports = trueを設定してください。

const { getDefaultConfig } = require("metro-config");
const config = getDefaultConfig(__dirname);
config.resolver.unstable_enablePackageExports = true;
module.exports = config;

セットアップ

Providerのセットアップ

アプリをConversationProviderでラップして、ElevenAgentsの機能を有効にします。

import { ConversationProvider } from "@elevenlabs/react-native";
import React from "react";
function App() {
return (
<ConversationProvider>
<YourAppComponents />
</ConversationProvider>
);
}

@elevenlabs/react-nativeは、@elevenlabs/reactのConversationProviderとすべてのフックを 再エクスポートします。APIはWeb向けReact SDKと同一です。完全なAPIリファレンスはReact SDK ドキュメントを参照してください。

使用方法

React SDKのすべてのフックは、@elevenlabs/react-nativeから利用できます。

  • useConversation — すべての状態とメソッドを組み合わせた便利なフック
  • useConversationControls — アクションメソッド(startSession、endSessionなど)
  • useConversationStatus — 接続ステータス
  • useConversationInput — ミュート状態
  • useConversationMode — 発話/リスニング状態
  • useConversationFeedback — フィードバックの可否と送信
  • useConversationClientTool — 動的なクライアントツール登録
  • useRawConversation — 生の会話インスタンス

会話を開始する

import { useConversationControls, useConversationStatus } from "@elevenlabs/react-native";
import React from "react";
import { View, Text, Button } from "react-native";
function ConversationComponent() {
const { startSession, endSession } = useConversationControls();
const { status } = useConversationStatus();
const handleStart = async () => {
await startSession({
agentId: "agent_7101k5zvyjhmfg983brhmhkd98n6",
});
};
return (
<View>
<Text>Status: {status}</Text>
<Button
title={status === "connected" ? "End" : "Start"}
onPress={status === "connected" ? endSession : handleStart}
/>
</View>
);
}

プライベートエージェント、認証、クライアントツール、オーバーライド、その他すべての機能については、React SDKドキュメントを参照してください。

実装例

ElevenLabs Agents SDKを使用したReact Nativeコンポーネントの完全な例です。

import { ConversationProvider, useConversation } from "@elevenlabs/react-native";
import React, { useState } from "react";
import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
function ConversationScreen() {
const [isConnected, setIsConnected] = useState(false);
const conversation = useConversation({
onConnect: () => {
console.log("Connected to conversation");
setIsConnected(true);
},
onDisconnect: () => {
console.log("Disconnected from conversation");
setIsConnected(false);
},
onMessage: (message) => {
console.log("Message received:", message);
},
onError: (error) => {
console.error("Conversation error:", error);
},
});
const startConversation = async () => {
try {
await conversation.startSession({
agentId: "agent_7101k5zvyjhmfg983brhmhkd98n6",
});
} catch (error) {
console.error("Failed to start conversation:", error);
}
};
const endConversation = async () => {
try {
await conversation.endSession();
} catch (error) {
console.error("Failed to end conversation:", error);
}
};
return (
<View style={styles.container}>
<Text style={styles.status}>Status: {conversation.status}</Text>
<Text style={styles.speaking}>
Agent is {conversation.isSpeaking ? "speaking" : "not speaking"}
</Text>
<TouchableOpacity
style={[styles.button, isConnected && styles.buttonActive]}
onPress={isConnected ? endConversation : startConversation}
>
<Text style={styles.buttonText}>
{isConnected ? "End Conversation" : "Start Conversation"}
</Text>
</TouchableOpacity>
{conversation.canSendFeedback && (
<View style={styles.feedbackContainer}>
<TouchableOpacity
style={styles.feedbackButton}
onPress={() => conversation.sendFeedback(true)}
>
<Text>👍</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.feedbackButton}
onPress={() => conversation.sendFeedback(false)}
>
<Text>👎</Text>
</TouchableOpacity>
</View>
)}
</View>
);
}
function App() {
return (
<ConversationProvider>
<ConversationScreen />
</ConversationProvider>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
padding: 20,
},
status: {
fontSize: 16,
marginBottom: 10,
},
speaking: {
fontSize: 14,
marginBottom: 20,
color: "#666",
},
button: {
backgroundColor: "#007AFF",
paddingHorizontal: 20,
paddingVertical: 10,
borderRadius: 8,
marginBottom: 20,
},
buttonActive: {
backgroundColor: "#FF3B30",
},
buttonText: {
color: "white",
fontSize: 16,
fontWeight: "600",
},
feedbackContainer: {
flexDirection: "row",
gap: 10,
},
feedbackButton: {
backgroundColor: "#F2F2F7",
padding: 10,
borderRadius: 8,
},
});
export default App;

プラットフォーム固有の考慮事項

iOS

Info.plistでマイク権限が正しく設定されていることを確認してください。

<key>NSMicrophoneUsageDescription</key>
<string>This app needs microphone access to enable voice conversations with AI agents.</string>

Android

android/app/src/main/AndroidManifest.xmlにマイク権限を追加します。

<uses-permission android:name="android.permission.RECORD_AUDIO" />

会話を開始する前にランタイム権限をリクエストすることも検討してください。

import { PermissionsAndroid, Platform } from "react-native";
const requestMicrophonePermission = async () => {
if (Platform.OS === "android") {
const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.RECORD_AUDIO, {
title: "Microphone Permission",
message: "This app needs microphone access to enable voice conversations.",
buttonNeutral: "Ask Me Later",
buttonNegative: "Cancel",
buttonPositive: "OK",
});
return granted === PermissionsAndroid.RESULTS.GRANTED;
}
return true;
};