Back to Blog
·10 min read

How I Built a Marketplace with Real-Time Messaging Using the MERN Stack

ReactNode.jsMongoDBSocket.IO

I built a full-featured marketplace platform where users can list products, browse listings, and chat with sellers in real time. The stack: React, Node.js, Express, MongoDB, Socket.IO, and Cloudinary.

Key Functionalities

  • Product Listings — Sellers can create, edit, and delete product listings with multiple images
  • Image Uploads — Cloudinary handles image storage, transformation, and optimization
  • Real-Time Chat — Buyers and sellers can message each other instantly via Socket.IO
  • User Authentication — JWT-based auth with role separation between buyers and sellers
  • Search & Filters — Filter products by category, price range, and location
  • Responsive Storefront — A clean, mobile-friendly shopping experience

Problem: Real-Time Message Sync Across Tabs

Socket.IO worked great for live messaging, but users who opened multiple browser tabs would see messages duplicated or out of order. The root cause was each tab opening its own socket connection, and the server broadcast messages to all connections for that user. I fixed this by assigning a unique connectionId to each socket and deduplicating messages on the client using a Set of message IDs before rendering.

Problem: Cloudinary Upload Size & Format

Users were uploading massive uncompressed images that took forever. I added client-side image compression using the browser-image-compression library before uploading to Cloudinary. I also restricted formats to JPEG, PNG, and WebP, and set a 5MB limit on the server with proper error messages. This cut average upload time by 70%.

Problem: JWT Expiration During Active Chat

Users in the middle of a conversation would suddenly get logged out when their JWT expired. I implemented a silent refresh mechanism: the client intercepts 401 responses, hits a /refresh-token endpoint using the stored refresh token (HTTP-only cookie), gets a new access token, and retries the original request — all without interrupting the user's chat session.

Problem: MongoDB Query Performance

As product listings grew, search became slow. The fix: compound indexes on the fields used for filtering (category + price + createdAt) and text indexes for full-text search on product titles and descriptions. Query times dropped from 800ms to under 50ms.

Key Takeaways

Building a marketplace taught me that real-time features add significant complexity to both frontend and backend. Socket.IO is powerful but needs careful connection management. And always index your MongoDB queries from day one — retrofitting indexes on a live database is stressful.

Check out the live marketplace or view the source code.