Skip to content

React UI Kit

@rtcstack/ui-react provides a drop-in <VideoConference /> component and composable hooks for building custom UIs.

Installation

bash
pnpm add @rtcstack/ui-react @rtcstack/sdk livekit-client

Drop-in Usage

tsx
import { createCall } from '@rtcstack/sdk'
import { VideoConference } from '@rtcstack/ui-react'
import '@rtcstack/ui-react/styles.css'

const call = createCall({ token, url })
await call.connect()

function App() {
  return (
    <VideoConference
      call={call}
      onLeave={() => call.disconnect()}
    />
  )
}

<VideoConference /> renders the full conference UI: video grid, control bar, and an optional chat panel.

Props

PropTypeDescription
callCallA Call instance from createCall()
onLeave() => voidCalled when the user clicks Leave
theme'dark' | 'light'Color theme (default: 'dark')
showChatbooleanShow chat panel initially (default: false)

Hooks

All hooks must be used inside a <CallProvider> (which <VideoConference> sets up for you).

useConnectionState()

ts
const state = useConnectionState()
// 'idle' | 'connecting' | 'connected' | 'reconnecting' | 'disconnected'

useParticipants()

ts
const participants = useParticipants()  // Participant[]

useLocalParticipant()

ts
const local = useLocalParticipant()  // Participant | null

useActiveSpeakers()

ts
const speakers = useActiveSpeakers()  // Participant[]

useMessages()

ts
const messages = useMessages()  // Message[]

useDevices()

ts
const devices = useDevices()
// { audioinput: MediaDeviceInfo[], audiooutput: MediaDeviceInfo[], videoinput: MediaDeviceInfo[] }

useMediaControls()

ts
const { toggleMic, toggleCamera, startScreenShare, stopScreenShare } = useMediaControls()

Building a Custom UI

tsx
import { CallProvider, useParticipants, useMediaControls } from '@rtcstack/ui-react'

function MyConference({ call }: { call: Call }) {
  return (
    <CallProvider call={call}>
      <MyGrid />
      <MyControls />
    </CallProvider>
  )
}

function MyGrid() {
  const participants = useParticipants()
  return (
    <div className="grid">
      {participants.map(p => <MyTile key={p.id} participant={p} />)}
    </div>
  )
}

function MyControls() {
  const { toggleMic, toggleCamera } = useMediaControls()
  return (
    <div>
      <button onClick={toggleMic}>Mic</button>
      <button onClick={toggleCamera}>Camera</button>
    </div>
  )
}

Theming

Override CSS custom properties to match your brand:

css
:root {
  --rtc-accent: #your-brand-color;
  --rtc-bg: #1a1a2e;
  --rtc-surface-1: #16213e;
}

See Theming for the full list of design tokens.

Atomic Components

ComponentDescription
<VideoConference />Full drop-in conference
<VideoGrid />Participant video grid
<ControlBar />Mic/camera/screen/leave controls
<ChatPanel />Scrolling chat with input
<ParticipantVideo />Single participant tile