Skip to content

Repository files navigation

PepTalk

A lightweight real-time voice call application to explore WebRTC, Socket.IO, and real-time system design.

PepTalk focuses on creating temporary voice rooms with minimal friction. Hosts authenticate to create and moderate rooms, while guests can join directly using a room link.


Features

  • Temporary voice rooms
  • Authenticated hosts (Clerk)
  • Guest join via room link
  • Waiting room with host approval
  • Host moderation (mute, kick)
  • Automatic host reassignment
  • Real-time room updates using Socket.IO
  • WebRTC peer-to-peer media architecture

Tech Stack

Layer Technology
Frontend Next.js, React, TypeScript, Tailwind CSS
Authentication Clerk
Realtime Signaling Socket.IO
Media Transport WebRTC
Runtime Node.js

Architecture

Room Management

                  ┌─────────────────────────┐
                  │     Next.js Client      │
                  │   React + Tailwind UI   │
                  └────────────┬────────────┘
                               │
                         Socket.IO Events
                               │
                  ┌────────────▼────────────┐
                  │   Socket.IO Server      │
                  │                         │
                  │  • Room lifecycle       │
                  │  • Waiting room         │
                  │  • Host moderation      │
                  │  • Host reassignment    │
                  │  • State sync           │
                  └────────────┬────────────┘
                               │
                     In-memory Room Store

The Socket.IO server acts as the authoritative source of truth for room state. Every room operation (join, leave, admit, mute, kick, etc.) is performed on the server before being broadcast to connected clients.


WebRTC Connection

          Host Browser                     Guest Browser
     ┌─────────────────┐              ┌─────────────────┐
     │                 │              │                 │
     │ RTCPeerConnection│            │ RTCPeerConnection│
     │                 │              │                 │
     └────────┬────────┘              └────────┬────────┘
              │                                │
              │      Peer-to-Peer Audio        │
              └────────────────────────────────┘

PepTalk uses a mesh WebRTC topology, where every participant establishes a direct connection with every other participant. This keeps the architecture simple for small rooms while avoiding additional media infrastructure.


Signaling

WebRTC does not define how peers discover each other or exchange connection information. PepTalk reuses the existing Socket.IO server as its signaling server.

Host                 Socket.IO Server                 Guest
 │                          │                          │
 │────── Offer ─────────────>│                          │
 │                           │────── Offer ───────────>│
 │                           │<───── Answer ───────────│
 │<───── Answer ─────────────│                          │
 │                           │                          │
 │──── ICE Candidates ──────>│──── ICE Candidates ────>│
 │<─── ICE Candidates ───────│<─── ICE Candidates ─────│
 │                           │                          │
 └──────────── Peer Connection Established ────────────┘

Once signaling is complete, the media stream flows directly between browsers without passing through the server.

Socket.IO is responsible only for signaling and synchronizing room state. Once peers negotiate a connection, media is exchanged directly between browsers using WebRTC.


Room Flow

Guest joins room
        │
        ▼
 Waiting Room
        │
        ▼
 Host approves
        │
        ▼
 Added to room
        │
        ▼
 Offer / Answer
        │
        ▼
 ICE Exchange
        │
        ▼
 Peer Connection

Design Decisions

Why Next.js?

This project intentionally keeps the frontend lightweight. Next.js provided built-in routing and server capabilities without requiring additional project setup.

Why an in-memory room store?

Rooms are temporary and the application targets a single server with a maximum of six participants. Introducing Redis would have added infrastructure complexity without much benefit for the MVP.

Why only hosts authenticate?

Guests should be able to join with minimal friction, while privileged actions (creating rooms, admitting users, kicking participants, muting participants) require authentication.

Why limit rooms to six participants?

PepTalk uses a mesh WebRTC topology where every participant maintains a direct connection with every other participant. This is simple to implement for small rooms but does not scale well. Larger rooms would require an SFU-based architecture.


Future Improvements

  • Redis-backed room storage
  • TURN server support
  • SFU for larger rooms
  • Video and screen sharing
  • Persistent chat
  • Production deployment hardening

Running Locally

git clone <repo-url>
cd peptalk

npm install
npm run dev

The Socket.IO signaling server should also be started before creating or joining rooms.


License

MIT

About

Lightweight Voice Call application

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages