DevsBooth

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.

A DevsBooth room titled “Is the TypeScript 7 compiler worth migrating to?”. Three speakers sit on stage, each with a level meter beside their initials, and the host can move the other two to the audience. Three listeners sit below, one with a raised hand. The bottom bar has an On air button, a microphone picker, Copy link and End room.

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.

The rooms list. Each row shows a topic, the room type, the people on stage and how many are in the room. Live rooms have a red lamp. Above the list are a topic search field and a Start a room button.
The rooms list, with live participant counts and topic search.

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.

  1. Clone the repository

    git clone https://github.com/danieltyukov/devsbooth.git && cd devsbooth
  2. Configure it

    cp .env.example .env

    Then set two values in .env:

    APP_URL=https://booth.example.com
    SMTP_URL=smtps://user:password@smtp.example.com:465

    APP_URL is the address people open. It has to use https in production, because browsers only allow microphone access on https and on localhost. SMTP_URL is the mail server for sign-in codes. Without it the codes are printed in the server log, which is enough for a trial run.

  3. Start it

    docker compose up -d

    DevsBooth 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=1 in .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, set LIVEKIT_URL and audio goes through a LiveKit SFU, which carries hundreds per room. One server process is the default; with REDIS_URL several 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.