Loading...
Loading...
Build custom React UIs with LiveKit hooks from @livekit/components-react. Use this skill when you need low-level control over agent state, participants, tracks, chat, and data channels. For pre-built UI components, use the livekit-agents-ui skill instead.
npx skill4agent add codestackr/livekit-skills react-hooksdocs_searchget_pagesget_changelogcode_searchget_python_agent_example@livekit/components-react@livekit/components-reactAgentSessionProviderAgentControlBarAgentAudioVisualizerBar/Grid/RadialAgentChatTranscriptnpm install @livekit/components-react livekit-clientAgentSessionProvideruseSessionAgentSessionProvideruseSessionimport { useRef, useEffect } from 'react';
import { useSession } from '@livekit/components-react';
import { TokenSource, TokenSourceConfigurable } from 'livekit-client';
import { AgentSessionProvider } from '@/components/agents-ui/agent-session-provider';
function App() {
const tokenSource: TokenSourceConfigurable = useRef(
TokenSource.endpoint('/api/token')
).current;
// Create session using useSession hook (required for AgentSessionProvider)
const session = useSession(tokenSource, { agentName: 'your-agent' });
useEffect(() => {
session.start();
return () => session.end();
}, []);
return (
<AgentSessionProvider session={session}>
<MyAgentUI />
</AgentSessionProvider>
);
}useVoiceAssistantimport { useVoiceAssistant } from '@livekit/components-react';
// This component must be inside an AgentSessionProvider
function CustomAgentStatus() {
const { state, audioTrack, agentTranscriptions } = useVoiceAssistant();
return (
<div>
<p>Agent state: {state}</p>
{agentTranscriptions.map((t) => (
<p key={t.id}>{t.text}</p>
))}
</div>
);
}import { useTrackToggle } from '@livekit/components-react';
import { Track } from 'livekit-client';
// Use this inside an AgentSessionProvider for custom toggle behavior
function CustomMicrophoneButton() {
const { enabled, toggle, pending } = useTrackToggle({
source: Track.Source.Microphone,
});
return (
<button onClick={() => toggle()} disabled={pending}>
{enabled ? 'Mute' : 'Unmute'}
</button>
);
}Note: This pattern uses UI components fromdirectly. For agent applications, use@livekit/components-reactfrom livekit-agents-ui instead, which wraps these components and provides a better developer experience.AgentSessionProvider
useSessionSessionProviderRoomAudioRendererAgentSessionProviderimport { useEffect, useRef } from 'react';
import { useSession, useAgent, SessionProvider, RoomAudioRenderer } from '@livekit/components-react';
import { TokenSource, TokenSourceConfigurable } from 'livekit-client';
function AgentApp() {
// Use useRef to prevent recreating TokenSource on each render
const tokenSource: TokenSourceConfigurable = useRef(
TokenSource.sandboxTokenServer('your-sandbox-id')
).current;
const session = useSession(tokenSource, {
agentName: 'your-agent-name',
});
const agent = useAgent(session);
// Auto-start session with cleanup
useEffect(() => {
session.start();
return () => {
session.end();
};
}, []);
return (
<SessionProvider session={session}>
<RoomAudioRenderer />
<div>
<p>Connection: {session.connectionState}</p>
<p>Agent: {agent.state}</p>
</div>
</SessionProvider>
);
}TokenSource.endpoint()const tokenSource: TokenSourceConfigurable = useRef(
TokenSource.endpoint('/api/token')
).current;
const session = useSession(tokenSource, {
roomName: 'my-room',
participantIdentity: 'user-123',
participantName: 'John',
agentName: 'my-agent',
});useParticipants()useLocalParticipant()useRemoteParticipants()useRemoteParticipant(identity)useParticipantInfo()useParticipantAttributes()useTracks(sources)useParticipantTracks(sources, identity)useTrackToggle({ source })useIsMuted(trackRef)useIsSpeaking(participant)useTrackVolume(track)useConnectionState()useRoomInfo()useLiveKitRoom(props)useIsRecording()useMediaDeviceSelect({ kind })AgentSessionProvideruseSession(tokenSource, options)AgentSessionProvideruseSessionMessages(session)useVoiceAssistant()AgentSessionProvideruseAgent(session)useSessionuseChat()useDataChannel(topic)useTextStream(topic)useTranscriptions()useEvents(instance, event, handler)useSessionAgentSessionProviderAgentSessionProviderSessionProviderRoomAudioRendereruseVoiceAssistantuseTrackToggleuseChatimport { useRef, useEffect } from 'react';
import { useSession, useVoiceAssistant } from '@livekit/components-react';
import { TokenSource, TokenSourceConfigurable } from 'livekit-client';
import { AgentSessionProvider } from '@/components/agents-ui/agent-session-provider';
function App() {
const tokenSource: TokenSourceConfigurable = useRef(
TokenSource.endpoint('/api/token')
).current;
// Create session using useSession hook (required)
const session = useSession(tokenSource, { agentName: 'your-agent' });
useEffect(() => {
session.start();
return () => session.end();
}, []);
return (
<AgentSessionProvider session={session}>
{/* Hooks from @livekit/components-react work here */}
<MyAgentComponent />
</AgentSessionProvider>
);
}
function MyAgentComponent() {
// useVoiceAssistant works inside AgentSessionProvider
const { state, audioTrack } = useVoiceAssistant();
return <div>Agent: {state}</div>;
}Note: This pattern uses UI components fromdirectly. For agent applications, use Option 1 with@livekit/components-reactfrom livekit-agents-ui instead.AgentSessionProvider
RoomAudioRendererimport { useRef, useEffect } from 'react';
import { useSession, useAgent, SessionProvider, RoomAudioRenderer } from '@livekit/components-react';
import { TokenSource, TokenSourceConfigurable } from 'livekit-client';
function App() {
const tokenSource: TokenSourceConfigurable = useRef(
TokenSource.sandboxTokenServer('your-sandbox-id')
).current;
const session = useSession(tokenSource, { agentName: 'your-agent' });
const agent = useAgent(session); // Pass session explicitly when using useSession
useEffect(() => {
session.start();
return () => session.end();
}, []);
return (
<SessionProvider session={session}>
<RoomAudioRenderer />
<MyAgentComponent agent={agent} />
</SessionProvider>
);
}updateOnlyOnuseConnectionState()useRefTokenSourceuseSessionAgentSessionProviderAgentSessionProviderAgentSessionProvideruseVoiceAssistantuseAgentimport { useVoiceAssistant } from '@livekit/components-react';
function AgentDisplay() {
const { state, audioTrack, agentTranscriptions } = useVoiceAssistant();
// state: "disconnected" | "connecting" | "initializing" | "listening" | "thinking" | "speaking"
}useAgent'idle''pre-connect-buffering''failed'const agent = useAgent(session);
if (agent.state === 'failed') {
console.error('Agent failed:', agent.failureReasons);
}
if (agent.isPending) {
// Show loading state
}useSessionAgentSessionProvideruseTrackToggleuseMediaDeviceSelectuseEventsuseEvents(agent, AgentEvent.StateChanged, (state) => {
console.log('Agent state:', state);
});@livekit/components-reactuseSessionuseSessionMessagesuseAgentuseVoiceAssistantuseTextStreamuseTranscriptions