Audio rooms for developers.
Open a room, talk through what you are building, and let people drop in to listen or take the mic. DevsBooth is open source and runs on your own server.
How a room works
Every room has a topic and a host. Speakers sit on stage and talk. Everyone else listens from the audience.
- Listeners
- Join muted. To say something, raise your hand and wait for the host to bring you up.
- Speakers
- Pick a microphone and talk. Each speaker has a live level meter, and the On air button mutes and unmutes you.
- The host
- Invites listeners to speak, moves speakers back to the audience and can end the room. A room that stays empty ends on its own after five minutes.
People sign in with an 8-digit code sent to their email, then choose a name and a unique username. A photo and a bio are optional. Profiles show who someone follows and who follows them.
Who can find a room
- Open
- Listed for everyone. Anyone signed in can join.
- Followers
- Listed for people who follow the host, and only they can join.
- Private
- Not listed. Anyone signed in who has the link can join.
Self-host it
You need a server with Docker Compose. The compose file runs the DevsBooth image from
ghcr.io/danieltyukov/devsbooth next to MongoDB 8.2, and keeps data in Docker
volumes.
Strict networks
Audio goes straight between browsers, with a public STUN server to help them connect. People
behind strict NATs or corporate firewalls may not hear each other until you add a TURN server
to
ICE_SERVERS.
For TURN, reverse proxies and the remaining settings, read the self-hosting guide.
-
Clone the repository
git clone https://github.com/danieltyukov/devsbooth.git && cd devsbooth -
Configure it
cp .env.example .envThen set two values in
.env:APP_URL=https://booth.example.com SMTP_URL=smtps://user:password@smtp.example.com:465APP_URLis the address people open. It has to use https in production, because browsers only allow microphone access on https and on localhost.SMTP_URLis the mail server for sign-in codes. Without it the codes are printed in the server log, which is enough for a trial run. -
Start it
docker compose up -dDevsBooth listens on port 3000. Put a reverse proxy with TLS in front of it, make sure the proxy passes WebSocket upgrades, and set
TRUST_PROXY=1in.env.
Under the hood
TypeScript throughout. One Node.js process serves the web client, the API and the signaling socket.
- Audio
- WebRTC in a full mesh by default: every pair of browsers in a room holds a direct connection, and speakers send their microphone over it. With a LiveKit SFU, speakers upload once and the SFU forwards their audio and enforces who may speak.
- Signaling
- Socket.IO on Express 5. The server passes connection offers between browsers and tracks who is in each room, who is on stage and whose hand is up. Audio never goes through it.
- Data
- MongoDB holds accounts, profiles, follows, rooms and sessions.
- Sign-in
- An 8-digit code sent by email. A code expires after 10 minutes, allows three guesses and only works in the browser that asked for it.
- Web client
- React 19 and Vite.
- Tests
- Server integration tests, web unit tests and Playwright end-to-end tests. In the end-to-end suite two browsers with fake microphones join a room, and the test checks that audio actually arrives.
- Limits
-
A full mesh suits small rooms, since every speaker uploads a separate stream to each person in
the room. The default cap is 25 people per room, set by
ROOM_MAX_PARTICIPANTS. For bigger rooms, setLIVEKIT_URLand audio goes through a LiveKit SFU, which carries hundreds per room. One server process is the default; withREDIS_URLseveral share presence through Redis.
Contribute
Fixes and features are welcome. Start with CONTRIBUTING.md, or pick one of the good first issues.
A working local setup needs Node.js 22 and no accounts:
npm install && npm run dev
This starts a local MongoDB, the server and the web client on
http://localhost:5173. Sign-in codes show up in the terminal.