I built this to really understand two things: how real-time database updates propagate across clients, and how end-to-end encryption works in a chat context. The first part is working. E2E encryption is the active focus - it turns out to be a more interesting problem than it looks.
Features
- Real-time message sync across clients
- Chat rooms
- Clean UI with shadcn/ui
Key decisions
- Live subscriptions over polling — polling requires managing intervals and introduces artificial latency; subscriptions let the database push diffs directly to the client as they happen, which is the right model for a chat app where latency is user-visible
- Drizzle over Prisma for explicit migration files — schema changes in version-controlled SQL files are reviewable and auditable; Prisma generates migrations behind the scenes in a way that’s harder to inspect and reason about
- E2E encryption requires key exchange without a trusted server — the server can never hold decryption keys; the key distribution problem has to be solved entirely on the client, which is why it’s harder than server-side encryption and why most chat apps don’t do it properly
Future directions
- End-to-end encryption with client-side key management
- Migrate remaining state from Firebase to PostgreSQL
Built with
- Next.js
- shadcn/ui
- Drizzle ORM
- PostgreSQL on Turso
- Deployed on Vercel