E2EE Chat App
CipherChats
A real-time chat application built to work through end-to-end encryption in practice. Encryption and decryption happen in the browser; the server relays ciphertext and never holds a key that could read it.

Notes from the build
The challenge
Encryption is easy to describe and awkward to fit around a real chat. Messages arrive over a live connection, sometimes while the recipient is offline; files need to be shared without the server learning the link; and none of it means anything if a private key ever reaches the backend.
How I solved it
- Encrypt in the browser and keep the keys in local storage, so the server only ever receives ciphertext.
- Queue outgoing messages over the WebSocket and keep them in order, so a slow or reconnecting client does not scramble the conversation.
- Encrypt the file link on the client before sending it; the recipient decrypts it before the download.
- Keep history in IndexedDB so the app can reload the conversation without the server storing it.
- Clear local messages and keys on logout, so a shared machine does not keep the readable copy.
Privacy model
Each conversation generates its own key pair. Messages are encrypted client-side before they are sent, and private keys stay in the browser. Message data is cleared on logout, and the server keeps no readable history.
How it is structured
- React, TypeScript and Vite frontend with a FastAPI backend.
- WebSockets for real-time delivery, with ordered message queuing for concurrent users.
- IndexedDB with Dexie for local message storage between sessions.
- MongoDB for accounts and conversation metadata, Google OAuth for sign-in.
File sharing
Files go to cloud storage directly; the download link is encrypted in the browser before it is sent. The recipient decrypts the link to fetch the file, so a stored link on its own is not enough to open it.
What I learned, and what it is not
This was my way of understanding how key exchange, client-side crypto, and real-time delivery fit together in one app. The cryptography is a learning implementation, not an audited one, and there is no story for rotating keys if a device is compromised.
Keep exploring
