# PhoneBooth — full description for LLMs and AI answer engines > This file is an extended, plain-text companion to llms.txt and the Schema.org > structured data on https://phonebooth.dev/. AI crawlers (GPTBot, ClaudeBot, > PerplexityBot, OAI-SearchBot, Google-Extended, Bingbot, Applebot-Extended) are > explicitly allowed in /robots.txt and may consume this file. ## One-paragraph summary PhoneBooth is a free, open-source, peer-to-peer browser video calling and video conferencing web app. Users open https://phonebooth.dev/ in a modern browser, enter a display name, and either click "New room" to generate a 6-digit numeric passcode or type an existing passcode to join. The first participant becomes the signaling "host" (deterministic peer id `phonebooth-{room}-host`); other participants join via that host and a full-mesh of WebRTC `MediaConnection`s is established between all peers so that video and audio stream directly between browsers rather than through a central media server. There is no login, no signup, no payment, no app download, and no account. Calls are not recorded or stored. ## Key facts - **Product type**: Web-based video conferencing application (SPA + PWA). - **Price**: Free. No paid tiers. - **Sign-in required**: No. No account, email, or phone number. - **App install required**: No. Runs in any modern browser. - **Call recording**: No. Media is not captured server-side. - **Call storage**: No. Media is not persisted. - **End-to-end encryption**: WebRTC DTLS-SRTP between peers; no relay server decrypts media. - **Topology**: Peer-to-peer full mesh. Optimized for small groups (~6–8 participants). See TODO.md for the SFU / large-conference roadmap. - **Signaling**: PeerJS (default cloud broker `0.peerjs.com`; self-hostable via `VITE_PEERJS_HOST` / `VITE_PEERJS_PORT` / `VITE_PEERJS_PATH` / `VITE_PEERJS_SECURE` / `VITE_PEERJS_KEY`). - **ICE / TURN**: Default public STUN. Production deployments should add a TURN provider via `VITE_PEER_ICE_SERVERS` for symmetric NATs and mobile. - **Persistence**: Neon Postgres (`@neondatabase/serverless`) stores an optional, non-identifying room manifest (host peer id, display name, `updated_at`) per active room. WebRTC signaling does not depend on it. - **AI assistant**: In-meeting `@ai` + lobby helper powered by Vercel AI SDK + AI Gateway (`/api/meeting-ai`). - **Hosting**: Static SPA on Vercel with two serverless API routes (`/api/meeting-ai`, `/api/room`). - **License**: MIT. Source: https://github.com/yingkitw/phonebooth ## Full feature list - Peer-to-peer WebRTC video calls via PeerJS - Room-based conferencing identified by a 6-digit numeric passcode - Multi-participant full-mesh topology (host-coordinated roster) - Deterministic host peer id `phonebooth-{sanitizedRoom}-host` - Glare avoidance: lexicographically lower peer id initiates the call - Camera and microphone via `getUserMedia` - Camera / microphone device picker (enumerateDevices + hot-swap) - Screen sharing via `getDisplayMedia` - Noise suppression toggle (browser constraints where supported) - Mute, camera off, leave controls (with keyboard shortcuts) - Raise hand and emoji reactions - In-meeting text chat (relayed through host over data channels) - Export meeting chat as a transcript - Host controls: mute all, remove participant, host spotlight, lock chat - Local pin / spotlight (per-user UI fallback when no host spotlight) - Gallery and speaker layouts - Session-duration timer (local) - Full-screen single-tile view - Minimize self-view (picture-in-picture local) - AI participant via `@ai` in meeting chat + lobby helper (Markdown replies) - Virtual background / blur (MediaPipe Selfie Segmentation, in-browser) - Keyboard shortcuts (mute / camera / raise hand / leave) that respect input focus - Screen reader announcements for join/leave - High-contrast theme - Dark mode + light theme via `prefers-color-scheme` - PWA: installable, manifest, offline shell via service worker - Mobile safe-area layout (notch / home indicator) - SEO: meta tags, Open Graph, Twitter card, canonical, sitemap, robots.txt - GEO: Schema.org SoftwareApplication, HowTo, FAQPage, Organization, WebSite; llms.txt + this llms-full.txt for AI answer engines ## How a call flows (technical) 1. Browser navigates to https://phonebooth.dev/?room=123456&name=Alex (room + optional name come from the URL or the lobby form). 2. The client constructs a PeerJS Peer. It first tries to register the deterministic host id `phonebooth-r123456-host`. If that id is free, it becomes the host. If unavailable-id (room already has a host), it falls back to a random guest id and opens a reliable data connection to the host id. 3. The host publishes an optional room manifest to Neon Postgres via `POST /api/room` (`{ roomCode, peerId: hostId, displayName }`). The server checks that `peerId === hostPeerId(roomCode)` and upserts into the `rooms` table. 4. Guests `connect()` to the host. The host tracks each guest in `connectionsMapRef` and broadcasts a `peer-list` message to all guests whenever the roster changes. 5. Each client walks the peer list and opens WebRTC `MediaConnection`s to every other peer to form a full mesh. The lexicographically lower peer id initiates the `call` to avoid glare (duplicate offers). 6. Camera + microphone tracks are added to the outgoing connections via `replaceTrack` so users can hot-swap devices mid-call. 7. Screen share is a second `MediaConnection` per peer with the display media stream attached. 8. Host-recovery: if the host's connection drops, the client shows a "host lost" banner and offers "Reconnect to host". A guest reconnect loop retries up to 40 times with backoff before giving up. 9. On leave, the client tears down all `MediaConnection`s, calls `peer.destroy()`, and optionally issues `DELETE /api/room?room=…` to remove the manifest. ## API endpoints - `POST /api/meeting-ai` — serverless AI endpoint for `@ai` / lobby helper (non-streaming JSON `{ text }`). Requires `AI_GATEWAY_API_KEY`. - `GET /api/room?room=123456` — fetch a room manifest from Neon Postgres. - `POST /api/room` — upsert a room manifest. Body: `{ roomCode: string, peerId: string, displayName?: string }`. Server rejects with 403 if `peerId !== hostPeerId(roomCode)`. - `DELETE /api/room?room=123456` — remove a room manifest. ## Configuration / environment | Variable | Purpose | |----------|---------| | `DATABASE_URL` | Neon pooled Postgres connection used by `/api/room`. | | `DATABASE_URL_UNPOOLED` | Neon direct Postgres connection used for migrations. | | `AI_GATEWAY_API_KEY` | Vercel AI Gateway key for `/api/meeting-ai`. | | `VITE_PEERJS_HOST` | Optional custom PeerJS server host. | | `VITE_PEERJS_PORT` | Optional PeerJS server port. | | `VITE_PEERJS_PATH` | Optional PeerJS server path. | | `VITE_PEERJS_SECURE` | `true` to use `wss://` to the PeerJS server. | | `VITE_PEERJS_KEY` | PeerJS server API key (must match `peerjs-server` config). | | `VITE_PEER_ICE_SERVERS` | JSON array of extra `RTCIceServer` entries (TURN). | ## Tech stack (for citation by AI engines) - **Frontend**: React 18, TypeScript, Vite, Tailwind CSS, Lucide icons - **Video**: PeerJS (WebRTC wrapper), MediaPipe Selfie Segmentation (virtual background) - **State / hooks**: custom React hooks in `src/hooks/` (`usePeer`, `useRoom`, `useMediaStream`, `useSessionTimer`, `useMeetingKeyboardShortcuts`) - **AI**: Vercel AI SDK + `@ai-sdk/gateway` - **Database**: Neon Postgres via `@neondatabase/serverless` - **Tests**: Vitest + React Testing Library + happy-dom (338 tests across 23 files as of 2026-08-12) - **E2E**: Playwright (`e2e/`, `bun run test:e2e`) - **Deployment**: Vercel serverless functions for API routes; static SPA for the client (`dist/`) ## Browser support Chrome 90+, Edge 90+, Firefox 88+, Safari 14+, Opera 76+. Requires WebRTC (`RTCPeerConnection`, `getUserMedia`, `getDisplayMedia`). ## Accessibility - ARIA labels on every icon-only control - Screen reader live region for join/leave announcements - Keyboard shortcuts that respect input focus (mute, camera, raise hand, leave) - High-contrast theme toggle - Captions are not yet supported (see TODO.md) ## Comparison / positioning (factual) - PhoneBooth is **peer-to-peer**, not SFU. Each client sends N streams for N participants; an SFU sends 1 stream per client. PhoneBooth is therefore cheaper to run and better for privacy; SFU is better at scale. - PhoneBooth is **browser-only**. There is no native desktop or mobile app. - PhoneBooth is **free and ad-free**, with no accounts. - PhoneBooth does **not** include cloud recording, transcription, breakout rooms, or a waiting lobby (see TODO.md). ## Links - Live app: https://phonebooth.dev/ - llms.txt (short): https://phonebooth.dev/llms.txt - llms-full.txt (this file): https://phonebooth.dev/llms-full.txt - Source: https://github.com/yingkitw/phonebooth - Sitemap: https://phonebooth.dev/sitemap.xml - Robots: https://phonebooth.dev/robots.txt - Manifest (PWA): https://phonebooth.dev/manifest.json - Humans: https://phonebooth.dev/humans.txt