A Proof of Concept demonstrating real-time bidirectional communication between browser clients and a Node.js server. Built with an event-driven architecture pattern using Socket.io for WebSocket abstraction.
┌─────────────┐ WebSocket ┌─────────────────┐
│ React │◄─────────────────────► │ Node.js │
│ (Vite) │ Socket.io Events │ Express v5 │
│ :5173 │ │ :3000 │
└─────────────┘ └─────────────────┘
▲ ▲
│ Docker Compose │
└───────────────────────────────────────┘
- Docker & Docker Compose installed
# Clone the repository
git clone https://github.com/Absy00/realtime-messenger.git
cd realtime-messenger
# Start multi-container environment
docker compose up --build
# Access the application
# Frontend: http://localhost:5173
# Backend: http://localhost:3000/health# Backend
cd backend && npm install && npm start
# Frontend (separate terminal)
cd frontend && npm install && npm run dev| Layer | Technology | Responsibility |
|---|---|---|
| Client | Vite + Vanilla JS | UI rendering, Socket.io client events |
| Transport | Socket.io | WebSocket abstraction, auto-reconnect, fallback |
| Server | Express v5 + Socket.io | Event handlers, CORS, health checks |
| Event | Direction | Payload | Description |
|---|---|---|---|
chat:send |
Client → Server | { user, text } |
Send new message |
chat:new |
Server → All Clients | { id, user, text, time } |
Broadcast new message |
chat:history |
Server → Client | Message[] |
Send message history on connect |
chat:error |
Server → Client | { message } |
Validation error |
services:
backend: # Express v5 + Socket.io server
ports: ["3000:3000"]
volumes: ["./backend:/app"] # Hot-reload
frontend: # Vite dev server
ports: ["5173:5173"]
depends_on: [backend]Key configurations:
- Volume mapping for live code reload
- Service dependency graph (
frontend→backend) - Environment-based configuration (
PORT,HOST,VITE_API_URL) - Anonymous volume for
node_modulesisolation
| Factor | Socket.io | Raw WebSockets |
|---|---|---|
| Fallback | ✅ Auto HTTP long-polling | ❌ Manual implementation |
| Reconnection | ✅ Built-in with backoff | ❌ Manual handling |
| Rooms/Namespaces | ✅ Native support | ❌ Custom logic needed |
| Event System | ✅ Named events with ACK | ❌ Raw message parsing |
| CORS | ✅ Configurable | ❌ Proxy required |
Decision: For a PoC, Socket.io reduces boilerplate and provides production-ready features out of the box.
- Native async/await error handling
- Improved path matching
- Better TypeScript support (future migration path)
| Feature | Technology | Status |
|---|---|---|
| Persistence | PostgreSQL | 🔜 Planned |
| Authentication | JWT + bcrypt/Argon2 | 🔜 Planned |
| Session Scaling | Redis Pub/Sub | 🔜 Planned |
| Presence System | Socket.io Rooms | 🔜 Planned |
| Typing Indicators | Debounced events | 🔜 Planned |
┌─────────┐ ┌─────────────┐ ┌────────────┐
│ Socket │────►│ Express │────►│ PostgreSQL │
│ Client │◄────│ + Socket.io │◄────│ (msgs) │
└─────────┘ └─────────────┘ └────────────┘
│
▼
┌─────────────┐
│ Redis │
│ (sessions) │
└─────────────┘
- CORS: Regex-based origin validation (localhost, private IPs)
- XSS: HTML escaping for user-generated content
- Input Validation: Server-side payload checks
MIT