Skip to main content

@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 dependencyVersionNotes
react>=18Required
react-dom>=18Required
@comm-baas/client-sdkSame lockstep versionRequired
livekit-client>=2Optional — 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.

PropTypeRequiredDescription
baseUrlstringYesBase URL of the platform API.
tokenstring | () => Promise<string>YesStatic JWT or async token provider.

RoomProvider

Room-scoped provider. Joins the room, establishes signaling, and synchronizes participant state. Auto-cleans up on unmount.

PropTypeRequiredDescription
roomIdstringYesThe room to join.
joinOptionsJoinOptionsNoOptions 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.

MethodSignatureDescription
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

ValueDescription
'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.