EphemeralChat is a privacy-first, real-time 1-to-1 chat app built so conversations stay between peers. Messages travel directly over WebRTC DataChannels, and the server is used only for short-lived signaling during room setup.
There is no database, no message persistence, and no third-party chat backend relaying your conversation. That makes the app a good fit for private, temporary communication where you do not want chats stored, indexed, or replayed later.
Most chat products optimize for retention, analytics, and long-term storage. EphemeralChat is built for the opposite use case: fast, disposable conversations with minimal surface area and no content history.
- Peer-to-peer chat over WebRTC DataChannels
- Zero message persistence
- No database for chat content
- Short-lived signaling only for room negotiation
- One-click room creation and shareable room links
- Minimal UI focused on fast access and clarity
- Built with TypeScript for safer, maintainable code
- Messages are not stored on a central server.
- The signaling server only exchanges SDP and ICE information needed to connect peers.
- Room traffic is not routed through a message relay once the data channel is established.
- The app avoids unnecessary third-party processing of chat content.
- Frontend: Next.js 14, React 18, Tailwind CSS 3
- Signaling: Cloudflare Workers + Durable Objects
- Transport: WebRTC with STUN-only ICE in V1
apps/web- Next.js frontendapps/signaling- Cloudflare Worker signaling serviceDEPLOYMENT.md- production deployment guide
- Node.js 20+
- pnpm 8+
pnpm install
cp .env.example apps/web/.env.localMake sure apps/web/.env.local contains:
NEXT_PUBLIC_SIGNALING_URL=ws://localhost:8787Start the signaling server:
pnpm dev:signalingIn a second terminal, start the web app:
pnpm dev:webThen open the local app, create a room, copy the link, and open it in a second tab to test the full flow.
| Variable | App | Description |
|---|---|---|
NEXT_PUBLIC_SIGNALING_URL |
web | WebSocket base URL for signaling, such as ws://localhost:8787 in development or wss://your-worker.workers.dev in production |
| Command | Description |
|---|---|
pnpm dev:web |
Start the Next.js dev server |
pnpm dev:signaling |
Start the Wrangler dev server |
pnpm build |
Build all packages |
pnpm typecheck |
Run TypeScript checks across the workspace |
pnpm lint |
Lint all packages |
pnpm test |
Run unit tests |
See DEPLOYMENT.md for the full production deployment guide.
flowchart LR
A[Browser A] <-- WebRTC DataChannel --> B[Browser B]
A <-- SDP/ICE signaling --> S[Cloudflare Worker]
B <-- SDP/ICE signaling --> S
S --- D[(Durable Object per room)]
After the DataChannel opens, message bytes no longer pass through the server.
- No TURN server, so some restrictive networks may fail to connect
- No reconnect after page refresh
- STUN-only ICE in V1
Apache 2.0