2025

ChatApp

Real-Time E2EE & WebRTC Media Communications Platform.

ChatApp
E2EE AES-256Encryption
WebRTC P2PVoice & Video
Socket.IORealtime Delivery
30-Day PersistenceSession Auth
Security & ArchitectureE2EE & WebRTC

Real-Time E2EE & WebRTC Media Communications Platform

A full-stack, enterprise-grade real-time web application featuring End-to-End Encryption (E2EE), WebRTC Voice & Video Calling, Bi-directional Socket.IO Messaging, and a responsive Glassmorphic UI. Built with extreme focus on cryptographic security, persistent sessions, performance, and cross-platform browser support.

License: MITReact 18.x (Vite)Node.js 18.x + ExpressWebRTC Peer-to-PeerE2EE ECDH P-256 + AES-GCM-256Socket.IO v4.xBetter Auth (30-Day Session)MongoDB + Mongoose

🔒 End-to-End Encryption (E2EE)

  • Asymmetric Key Exchange: Uses Elliptic Curve Diffie-Hellman (ECDH P-256) via the native Web Crypto API.
  • Symmetric Payload Encryption: Scrambles message payloads on device using AES-GCM-256 with random 12-byte initialization vectors (iv). Zero plain text is ever stored on the server or database.
  • JWK Storage Serialization: Converts raw crypto handles into standard JSON Web Key (JWK) format stored in IndexedDB & localStorage, guaranteeing 100% key persistence across browser reloads, mobile cold starts, and device restarts.

📞 WebRTC Voice & Video Calling

  • Real-Time P2P Signaling: Socket.IO relay for WebRTC offer, answer, ice_candidate, and real-time toggle_media state synchronization.
  • Glassmorphic Calling Overlay: Modern 100vw × 100vh call interface with picture-in-picture local camera feed, duration timer, and full responsive controls.
  • Controls & Status Tracking: Live Mute/Unmute microphone, Camera On/Off, Audio Speaker Toggle API, and real-time remote mute badges.
  • Screen Sharing & Logging: Fixed-aspect remote view with mobile browser getDisplayMedia feature detection, plus automatic local call history with one-touch callback.
Peer-to-peer audio/video with STUN/TURN fallback

⚡ Real-Time Socket.IO Messaging

  • Bi-directional Delivery: Sub-50ms message sync with live typing indicators (isTyping), active user presence, emoji reactions, and unread counters.
  • Session & Offline Resiliency: Socket automatic reconnection recovery and offline message queueing via Service Workers (sync-chat-messages).
  • Rich Media: Cloudinary CDN integration with Multer multi-part file parsing for avatar and image attachments.
Low-latency WebSocket transport with HTTP long-polling fallback

🔑 30-Day Session Persistence

  • 30-Day Cookie Persistence: Configured Better Auth with explicit 30-day session expiry (expiresIn: 30 days), Partitioned cookies for WebViews, and SameSite=None attributes.
  • Instant Cold Start: Client-side localStorage state caching prevents mobile app cold-start login drops during network wake-up delays.
  • Multi-Provider Auth: Email & Password authentication paired with Google & GitHub OAuth integrations.
Zero session dropouts across PWA and mobile reboots

🏗️ End-to-End Encryption (E2EE) Lifecycle

Zero Plaintext Server Exposure
[ Alice's Browser ]                                  [ MongoDB / Server ]                                 [ Bob's Browser ]
        │                                                     │                                                    │
 1. Generate ECDH KeyPair ────────────────────────────────────┼────────────────────────────────────────────► 1. Generate ECDH KeyPair
    (Save PrivateKey to IndexedDB as JWK)                      │                                              (Save PrivateKey to IndexedDB as JWK)
        │                                                     │                                                    │
 2. Upload PublicKey_Alice (JWK) ────────────────────────────►│◄──────────────────────────── Upload PublicKey_Bob (JWK)
        │                                                     │                                                    │
 3. Fetch PublicKey_Bob ◄─────────────────────────────────────┤───────────────────────────────────── Fetch PublicKey_Alice
        │                                                     │                                                    │
 4. Derive SharedAESKey = ECDH(Priv_Alice, Pub_Bob)           │                                4. Derive SharedAESKey = ECDH(Priv_Bob, Pub_Alice)
        │                                                     │                                                    │
        │ ── 5. Encrypt "Hi" ──► Ciphertext: "x89Fk2..." ───►│── 6. Relay Ciphertext ────────────────────────► 7. Decrypt "x89Fk2..."
        │        (Using SharedAESKey + random IV)             │    (Server NEVER sees plaintext!)                 (Using SharedAESKey + random IV)

← Swipe horizontally to explore architecture diagram →

* For mathematical and protocol comparisons (Static ECDH vs. Signal Double Ratchet vs. MLS Group E2EE), inspect the full write-up in notes/E2EE.md.

🛠️ Complete Tech Stack & Cryptographic Standards

Cryptography & Protocols

  • Asymmetric: ECDH P-256
  • Symmetric: AES-GCM-256
  • Key Format: JWK (RFC 7517)
  • Real-Time Media: WebRTC + STUN/TURN
  • Transport: Socket.IO v4.x

Frontend Engineering

  • Framework: React 18 + Vite
  • Styling: Tailwind CSS + Glassmorphism
  • Animation: Framer Motion
  • State: React Context API
  • PWA & Storage: Service Workers + IndexedDB

Backend & Infrastructure

  • Runtime: Node.js (v18+)
  • Server: Express.js
  • Database: MongoDB + Mongoose ORM
  • Authentication: Better Auth (30-day)
  • Media & CDN: Cloudinary + Multer
  • Security: Helmet, CORS, Rate Limiting
Dev JournalThe Scalability Awakening

The feedback that completely changed how I think.

I was honestly super proud of this project.

So proud that I called one of my mentors and said:

"Sir, I built a chat app. Can I show you?" 😎

I gave him the full demo. Every feature, every flow, every little animation.

He started asking questions:

Authentication?
Messaging flow?
Database?
WebSockets?

For the first time, I could actually answer almost everything confidently.

I was already celebrating in my head... and then came the final feedback. 😂


"Good project. Now build it for 100,000 users."

He smiled and said:

"This is a great learning project. But if you ever build a chat app at scale, you'll need a completely different architecture."

And then he casually dropped 20+ new words into my life:

PhoenixElixirMQTTPub/SubPresenceDistributed systemsLoad balancersMessage brokers

I was just sitting there like... bro, what language are we speaking? 😭

He told me my architecture was efficient for learning, but not for 100,000 concurrent users.


It hurt a little... but it was exactly what I needed.

For a few minutes I was disappointed.

Then I realized this wasn't criticism — it was a roadmap.

That conversation made me curious about scalability instead of just features.

I started reading about real-time architectures, event-driven systems, message brokers, and why chat applications are way more complex than they look.

The Core Takeaway

Building a feature is one skill. Designing a system that survives millions of messages is a completely different game. 🚀