@comm-baas/react
React bindings for the EthioConnect platform. Provides hooks, context providers, and headless components that wrap @comm-baas/client-sdk, giving React applications a declarative interface for room participation.
All WebSocket signaling, session resume, and roster reconciliation are handled internally.
Installation
npm install @comm-baas/react @comm-baas/client-sdk livekit-client react react-dom
| Peer dependency | Version | Notes |
|---|---|---|
react | >=18 | Required |
react-dom | >=18 | Required |
@comm-baas/client-sdk | Same lockstep version | Required |
livekit-client | >=2 | Optional — install for media layer |
Quick Start
1. Wrap your app with CommBaasProvider
import { CommBaasProvider } from '@comm-baas/react';
function App() {
return (
<CommBaasProvider
baseUrl="https://api.comm-baas.example.com/v1"
token={async () => {
const res = await fetch('/api/token');
const { access_token } = await res.json();
return access_token;
}}
>
<Router />
</CommBaasProvider>
);
}
2. Wrap a room page with RoomProvider
import { RoomProvider } from '@comm-baas/react';
function RoomPage({ roomId }: { roomId: string }) {
return (
<RoomProvider roomId={roomId} joinOptions={{ display_name: 'Alice' }}>
<RoomView />
</RoomProvider>
);
}
3. Consume room state with hooks
import {
useParticipants,
useLocalMic,
useConnectionState,
AudioRenderer,
} from '@comm-baas/react';
function RoomView() {
const participants = useParticipants();
const connectionState = useConnectionState();
const { isMuted, toggle } = useLocalMic();
if (connectionState === 'connecting') return <p>Connecting...</p>;
return (
<div>
<h2>Participants ({participants.length})</h2>
<ul>
{participants.map((p) => (
<li key={p.user_id}>
{p.display_name} {p.is_muted ? '(muted)' : ''}
</li>
))}
</ul>
<button onClick={toggle}>{isMuted ? 'Unmute' : 'Mute'}</button>
<AudioRenderer />
</div>
);
}
Providers
CommBaasProvider
Top-level provider that creates the CommBaasClient instance.
| Prop | Type | Required | Description |
|---|---|---|---|
baseUrl | string | Yes | Base URL of the platform API. |
token | string | () => Promise<string> | Yes | Static JWT or async token provider. |
RoomProvider
Room-scoped provider. Joins the room, establishes signaling, and synchronizes participant state. Auto-cleans up on unmount.
| Prop | Type | Required | Description |
|---|---|---|---|
roomId | string | Yes | The room to join. |
joinOptions | JoinOptions | No | Options forwarded to the join call. |
Hooks
useClient()
Returns the CommBaasClient instance. Throws if called outside CommBaasProvider.
useRoom(roomId, options?)
Imperative hook for joining a room without RoomProvider. Returns { participants, connectionState, leave }.
useParticipants()
Returns the current participant roster as a reactive array. Updates on join, leave, mute, and role-change events.
Returns: RosterParticipant[] — { user_id, display_name, role, is_muted, joined_at }
useConnectionState()
Returns the signaling connection state: 'disconnected' | 'connecting' | 'connected' | 'resuming'.
useLocalMic()
Controls the local microphone. Returns { isMuted, toggle, setEnabled }.
useActiveSpeakers()
Returns an array of user IDs currently speaking, ordered by audio level.
useRecordingStatus()
Returns { isRecording: boolean }.
useModeration()
Returns moderation action functions or null if the local participant lacks permissions.
| Method | Signature | Description |
|---|---|---|
mute | (userId, track) => Promise<void> | Server-side mute. |
kick | (userId, reason?) => Promise<void> | Remove from room. |
ban | (userId, reason?) => Promise<void> | Ban from room. |
unban | (userId) => Promise<void> | Lift a ban. |
changeRole | (userId, role) => Promise<void> | Change participant role. |
Components
AudioRenderer
Headless component that manages <audio> elements for remote participants. Place once inside a RoomProvider. Requires livekit-client.
<AudioRenderer />
ConnectionState
| Value | Description |
|---|---|
'disconnected' | Not connected (initial state or after max retries). |
'connecting' | Establishing initial WebSocket connection. |
'connected' | WebSocket open, hello handshake complete. |
'resuming' | Reconnecting after unexpected disconnect. |