Building Real-Time Audio Rooms: A Clubhouse Clone in 30 Minutes
Remember when Clubhouse launched and suddenly every app wanted audio rooms? Twitter added Spaces. Spotify added Greenroom. Discord added Stage Channels.
The hype cooled, but audio rooms are now standard in social apps, community platforms, and corporate tools. Building them from scratch is surprisingly complex — real-time audio streaming, speaker/listener roles, dynamic participant management. Let's build one in 30 minutes.
What We're Building
Live audio rooms with speaker queue, hand-raising, moderator controls, participant list, recording, and optional text chat alongside.
Step 1: Set Up
npx create-react-app audio-rooms --template typescript
cd audio-rooms
npm install @wibechat/reactStep 2: Create the Audio Room
import { WibeChat, useAudioRoom } from '@wibechat/react'
function LiveRoom({ roomId }) {
const room = useAudioRoom(roomId)
return (
<div className="live-room">
<header>
<h2>{room.title}</h2>
<span>{room.participantCount} listening</span>
</header>
<section className="speakers">
<h3>Speakers</h3>
{room.speakers.map(speaker => (
<div key={speaker.id} className="speaker-card">
<img src={speaker.avatar} alt={speaker.name} />
<span>{speaker.name}</span>
{speaker.isTalking && <span className="talking-dot" />}
</div>
))}
</section>
{room.handRaised.length > 0 && (
<section>
<h3>Raised Hands</h3>
{room.handRaised.map(user => (
<div key={user.id}>
<span>{user.name}</span>
{room.isModerator && (
<button onClick={() => room.promote(user.id)}>Let Speak</button>
)}
</div>
))}
</section>
)}
<section className="listeners">
<h3>Listeners ({room.listeners.length})</h3>
{room.listeners.map(l => (
<img key={l.id} src={l.avatar} alt={l.name} />
))}
</section>
<footer>
{room.isSpeaker ? (
<button onClick={room.isMuted ? room.unmute : room.mute}>
{room.isMuted ? 'Unmute' : 'Mute'}
</button>
) : (
<button onClick={room.raise}>Raise Hand</button>
)}
<button onClick={room.leave}>Leave</button>
</footer>
</div>
)
}The useAudioRoom hook gives you everything: speakers, listeners, hand-raised queue, mute/unmute, raise/lower, promote/demote, and leave.
Step 3: Create a Room
const room = await WibeChat.audioRooms.create({
title: 'Design Chat: Building Better Developer Tools',
enableRecording: true,
enableChat: true,
maxSpeakers: 10,
public: true,
})Step 4: Add the Talking Indicator
.talking-dot {
width: 8px;
height: 8px;
background: #10B981;
border-radius: 50%;
animation: pulse 1s ease-in-out infinite;
}
.speaker-card img {
width: 72px;
height: 72px;
border-radius: 50%;
border: 3px solid transparent;
}
.speaker-card.talking img {
border-color: #10B981;
}Extending It
Scheduled rooms — Let users schedule and get push notifications when live. Chat alongside audio — Add a ChatWindow component next to the audio room. Reactions — Floating emoji reactions for listener engagement. Replays — Recorded rooms become podcast-like content.
Why Audio Rooms?
Audio rooms work because they're lower friction than video (no camera anxiety) and higher fidelity than text (tone, personality, real-time interaction). For social apps they drive engagement. For communities they create belonging. For corporate tools they replace some meetings.
Frequently Asked Questions
How many people can join an audio room?
Does it work on mobile?
Can I record sessions?
What about echo and noise?
Vishnu Raj
Software Engineer
Expert in real-time communication infrastructure and developer experiences.