Real-Time Chat banner

Real-Time Chat

A web-based real-time chat application

Real-Time Chat additional image 1 Real-Time Chat additional image 2

A practice project for building real-time web applications with WebSocket technology. Built to understand the challenges of event-driven architecture, persistent connections, and message delivery guarantees at small scale.

Stack

Layer Technology Why
Backend Node.js + Express + TypeScript Integrates well with Socket.io, fullstack TypeScript
Real-time Socket.io Handles WebSocket connections with fallback support and room management built in
Auth Custom (bcrypt) Intentional choice to avoid third-party auth and understand the fundamentals
Database PostgreSQL + MongoDB + Cassandra PostgreSQL for relational data (users, channel/server static information); MongoDB for frequent updates and high write throughput; Cassandra for high volume operations
Frontend React + TypeScript Fullstack TypeScript across backend and frontend
Deployment Docker Near full containerization (excluding frontend)

Features

Feature Description
Real-Time Messaging Instant message delivery via WebSockets with no polling
Chat Rooms Users can create and join multiple rooms to organize conversations
Direct Messaging Private one-to-one conversations between users
User Authentication Custom login and registration with bcrypt password hashing

Architecture

Backend follows a layered structure with controllers, services, and repositories. Socket.io is integrated into the Express server to handle WebSocket connections alongside RESTful API endpoints for authentication and data retrieval. Exposes a RESTful API for user management and chat history, while real-time messaging is handled through Socket.io. Active conversations are held in memory. Messages are persisted asynchronously based on triggers - message count thresholds or time intervals - to avoid blocking the event loop on every write. Authentication in WS is validated during the initial handshake and per operation. Messages are relayed and stored in Cassandra for high write throughput, while MongoDB is used for frequently updated data like user presence and channel metadata. PostgreSQL is reserved for relational data that benefits from strong consistency and complex queries.

Frontend is a React application that connects to the backend via REST for authentication and initial data loading, and establishes a WebSocket connection for real-time messaging after successful authentication. It manages chat rooms and direct messages with a simple UI that updates in real time as messages are sent and received.

Challenges

Designing hybrid architecture - balancing the use of REST for certain operations alongside WebSockets for real-time updates was more complex than expected. Deciding which operations should be RESTful (e.g., authentication, initial data loading) versus WebSocket-based (e.g., message sending, presence updates) required careful consideration of the user experience and technical constraints.

Three-Database Setup - managing what data goes where and ensuring consistency across PostgreSQL, MongoDB, and Cassandra added significant complexity. Each database has different strengths and tradeoffs, and orchestrating them together for a seamless experience was a non-trivial challenge.

What I’d Do Differently

Drop Cassandra. The complexity of managing three different databases outweighed the benefits at this scale. MongoDB alone could have handled the high write throughput use cases with proper schema design and indexing, while PostgreSQL could manage the relational data effectively. Cassandra’s advantages in horizontal scaling and high availability are not necessary for a project of this scope, and the operational overhead was not justified.

File storage and authentication via Firebase. Having already integrated Firebase in Vetly, the natural next step here would be replacing the custom auth and adding Firebase Storage for media - consolidating to a single service rather than introducing AWS S3 alongside a separate auth provider. The custom auth was worth building once to understand the fundamentals, but Firebase handles the edge cases (token refresh, session management, OAuth) more robustly for anything production-facing.

Tags

  • typescript
  • node.js
  • socket.io
  • express
  • react
  • websockets
  • mongodb
  • docker
  • cassandra
  • postgresql