Ephemeral, real-time chat rooms. No database, no message history on disk, no accounts. When a room expires, every trace of it is gone.
Live demo: https://secure-chat-one-zeta.vercel.app
Author: github.com/MohidUmer
- 🔒 Zero persistence — all room state lives in Redis with a hard TTL; nothing outlives the room
- ⏱ Self-destructing rooms — every room auto-purges after 60 minutes
- ⚡ Real-time messaging — instant delivery, typing indicators, live roster via Ably pub/sub
- 👑 Host authority — warn, mute, kick, and grant/revoke broadcast rights; host auto-promotes if the current host goes silent
- 📎 File sharing — up to 4 MB, images EXIF-scrubbed client-side before upload
- 😀 Custom emoji sets — drop PNGs into
static/assets/emoji/and they show up automatically
| Layer | Tech |
|---|---|
| Backend | Flask on Vercel serverless (Python) |
| State | Upstash Redis (TTL-based, serverless-native) |
| Real-time | Ably (pub/sub over WebSockets) |
| Frontend | Vanilla JS, no framework |
| Security | Flask-Talisman, per-session join tokens, EXIF stripping |
No install needed — SecureChat is live and ready to use:
👉 secure-chat-one-zeta.vercel.app
Create a room, share the link, start chatting. The room and everything in it disappears automatically after 60 minutes.
- Fork/clone this repo and push it to your own GitHub
- Create a free Upstash Redis database and a free Ably app
- Import the repo at vercel.com/new
- Add the four environment variables above in Project Settings → Environment Variables
- Deploy —
vercel.jsonhandles the rest
Vercel's Python functions are stateless and can't hold a persistent WebSocket open, so this app splits responsibilities:
- Upstash Redis stores everything about a room — profiles, messages, mutes, broadcast rights — under keys that share one TTL, so a room's data expires together as a unit.
- Ably delivers real-time events to browsers. The server publishes; clients only subscribe, never publish directly.
- A lightweight 15-second heartbeat from each client replaces WebSocket disconnect detection, since a serverless request can't observe a closed connection the way a long-running process can.