BackendMERN StackTutorialMongoDBReactNode.js2025

MERN Stack Project Tutorial 2025: Build a Blog Platform

Build a complete blog platform with the MERN stack in 2025 — MongoDB, Express, React, and Node.js with authentication, rich text editing, and deployment.

Abdur Razzak

Abdur Razzak

Full-Stack Web Developer

May 24, 2024 13 min read

What We Are Building

In this tutorial we will build a full-featured blog platform: users can register, create blog posts with a rich text editor, upload cover images, and publish to a public listing page. The backend is Node.js + Express + MongoDB. The frontend is React with React Query for data fetching. We will deploy the API to Render and the frontend to Vercel.

Backend Setup: Express + MongoDB

Initialize with npm init -y and install: express, mongoose, dotenv, cors, bcryptjs, jsonwebtoken, multer (for file uploads), and cloudinary (for image storage). Create a modular structure: src/modules/blog/{blog.model.js, blog.controller.js, blog.route.js}. Define a Mongoose Blog schema with title, slug (auto-generated), content, coverImage, author (ref to User), tags, and publishedAt.

Authentication with JWT

Create a User model with hashed passwords using bcryptjs. POST /api/auth/register creates a user. POST /api/auth/login returns a signed JWT (expires in 7d). An authMiddleware verifies the JWT on protected routes. Store the token in an httpOnly cookie or localStorage — for a blog platform, localStorage is acceptable since the admin is a single trusted user.

Image Upload with Cloudinary

Configure multer to accept image uploads in memory (memoryStorage). In your blog creation route, upload the buffer to Cloudinary using cloudinary.uploader.upload_stream(). Store the returned secure_url in the blog document. This approach avoids storing images on your server disk and gives you automatic CDN delivery, transformations, and format optimization (auto WebP for modern browsers).

React Frontend with React Query

Set up a React app with Vite and install: react-router-dom, @tanstack/react-query, axios, and a rich text editor (Tiptap or React Quill). Use React Query's useQuery to fetch and cache the blog list. Use useMutation for creating and updating posts. React Query automatically handles loading/error states and cache invalidation after mutations — no manual state management needed.

Deploying the MERN Blog

Push your backend to GitHub and connect it to Render (free tier). Set environment variables: MONGODB_URI (from MongoDB Atlas), JWT_SECRET, CLOUDINARY_URL. Push the React frontend to Vercel. Update your backend's CORS config to allow your Vercel domain. Update the React app's API base URL in a .env file. Verify the full flow: register → login → create post → see it on the public listing.

Share this article

All posts
#MERN Stack#Tutorial#MongoDB#React#Node.js#2025
Abdur Razzak — Full Stack Web Developer
⭐ Top Rated

Upwork Top Rated Developer

Work With a Developer Clients Trust