DEV Community

GHULAM SABIR
GHULAM SABIR

Posted on

Building a Production-Ready Chat Application: From Zero to Live

Building a Production-Ready Chat Application: A Full-Stack Journey

Introduction

I just built and deployed a production-ready chat application from scratch. Here's everything I learned about real-time messaging, authentication, and deployment.

Live App: https://chat-app-backend-floq.onrender.com

GitHub: https://github.com/engineersabir/chat-app-backend


What We Built

A full-stack real-time chat application with:

  • User authentication (signup/login with JWT)
  • Real-time messaging via WebSocket (Socket.io)
  • MongoDB database persistence
  • RESTful API
  • Production deployment

Tech Stack: Node.js | Express | Socket.io | MongoDB | JWT | JavaScript


Architecture Overview

Frontend

  • HTML5 + CSS3 + Vanilla JavaScript
  • Socket.io client for real-time updates
  • Clean, responsive UI

Backend

  • Express.js - REST API framework
  • Socket.io - WebSocket real-time communication
  • MongoDB - NoSQL database
  • JWT - Stateless authentication
  • Bcryptjs - Password hashing

Database

  • User schema with encrypted passwords
  • Message schema with auto-deletion
  • Proper indexing for performance

The Development Process

Phase 1: Project Setup (30 mins)

npm init -y
npm install express socket.io mongoose bcryptjs jsonwebtoken
Enter fullscreen mode Exit fullscreen mode

Organized the project with MVC architecture:### Phase 2: Authentication System (1 hour)

Built a secure signup/login system:

User Model

const userSchema = new Schema({
  username: { type: String, unique: true, required: true },
  email: { type: String, unique: true, required: true },
  password: { type: String, required: true },
  status: { enum: ['online', 'offline'], default: 'offline' }
});

// Hash password before saving
userSchema.pre('save', async function(next) {
  this.password = await bcrypt.hash(this.password, 10);
  next();
});
Enter fullscreen mode Exit fullscreen mode

Authentication Routes

  • /api/auth/signup - Register new users
  • /api/auth/login - Authenticate users & return JWT
  • /api/auth/users - Get all users

Key points:

  • JWT tokens expire after 7 days
  • Passwords hashed with bcrypt (10 salt rounds)
  • Proper error handling & validation

Phase 3: Real-Time Messaging (1 hour)

Implemented Socket.io for real-time communication:

io.on('connection', (socket) => {
  socket.on('send_message', async (data) => {
    // Save to MongoDB
    const message = new Message(data);
    await message.save();

    // Broadcast to all users
    io.emit('receive_message', message);
  });
});
Enter fullscreen mode Exit fullscreen mode

Message Model

  • Tracks sender, content, timestamp
  • Auto-deletes after 30 days
  • Indexed by timestamp for performance

Socket Events

  • user_join - User enters chat
  • send_message - User sends message
  • receive_message - Broadcast to all
  • typing - Show typing indicators
  • disconnect - User leaves

Phase 4: Production Deployment (30 mins)

Deployed on Render.com (free tier):

  1. Pushed code to GitHub
  2. Connected Render to GitHub repo
  3. Configured build & start commands
  4. Live in 2 minutes!

Key Learnings

1. Real-Time is Complex

  • Managing socket connections
  • Handling disconnects gracefully
  • Broadcasting to the right clients
  • Avoiding duplicate messages

2. Security Matters

  • Never store plain passwords
  • Validate all inputs
  • Use JWT for stateless auth
  • Implement CORS properly

3. Database Design

  • Proper schema modeling
  • Indexing for performance
  • Auto-deletion strategies
  • Data relationships

4. Professional Code Structure

  • Separation of concerns
  • Reusable middleware
  • Error handling
  • Environment configuration

API Endpoints

Authentication

  • POST /api/auth/signup - Register user
  • POST /api/auth/login - Login & get JWT
  • GET /api/auth/users - List all users

Messages

  • GET /api/messages - Get all messages
  • POST /api/messages - Save message (requires JWT)
  • DELETE /api/messages/:id - Delete message

Health Check

  • GET /health - Server status

Challenges & Solutions

Challenge 1: MongoDB Connection Issues

  • Problem: ISP blocking DNS resolution
  • Solution: Used environment variables, added connection pooling

Challenge 2: Socket.io CORS

  • Problem: Frontend couldn't connect to backend
  • Solution: Configured CORS in Socket.io initialization

Challenge 3: Message Persistence

  • Problem: Messages only in memory
  • Solution: Integrated MongoDB with proper schema

Performance Optimization

  1. Database Indexing

    • Index on timestamps for sorting
    • Index on sender for queries
  2. Connection Pooling

    • MongoDB connection reuse
  3. Message Limits

    • Auto-delete after 30 days
    • Query limits (last 100 messages)
  4. Stateless Backend

    • Easy horizontal scaling
    • Load balancer ready

What's Next?

Future enhancements:

  • React frontend rewrite
  • Private messaging
  • Chat rooms
  • Message search
  • File sharing
  • Voice messages
  • Read receipts

How to Run Locally

# Clone repo
git clone https://github.com/engineersabir/chat-app-backend.git

# Install dependencies
npm install

# Create .env
echo "MONGODB_URI=your_mongodb_uri" > .env

# Start server
node server.js

# Open http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

✅ Full-stack development is achievable

✅ Real-time communication with Socket.io is powerful

✅ Proper architecture scales

✅ Security must be built in from start

✅ Production deployment is easier than you think


Live Demo & Source Code

🌍 Live Application

💻 GitHub Repository


Connect With Me

I'm actively looking for web developer roles and collaborating on open-source projects.


Top comments (0)