How to Upload Images to Cloudinary Using MERN Stack (Step-by-Step Beginner Guide)
If you are building a MERN stack application and wondering how to upload images to Cloudinary properly, this guide will explain everything in a simple and practical way.
In this article, you will learn:
- Why we should not store images inside MongoDB
- Why local server storage fails after deployment
- How to upload images to Cloudinary using MERN stack step-by-step
- The role of Multer, routes, controller, and service layer
- How React frontend sends images to backend
- How to design a clean and scalable image upload architecture
By the end, you will understand not just the code — but the full architecture behind professional image uploads.
Why Storing Images Inside MERN Stack Is a Bad Idea
Many beginners try to store images directly inside MongoDB. Technically, it works. But practically, it creates problems.
MongoDB is designed for structured data like:
- User information
- Product details
- Orders
- Messages
It is not optimized for large binary files like images.
When you store images inside MongoDB:
- Database size increases rapidly
- Backups become heavy
- Performance decreases
Some developers save images in a local uploads folder. That works in development, but in production many hosting platforms reset storage during deployment.
So what is the correct solution?
Upload images to Cloudinary. Store only the image URL in MongoDB.
Let’s understand this with a simple example.
When you take admission in school, the office collects your full details — name, address, and photo. All these are stored safely in school records.
But inside the classroom, the teacher does not bring your full admission file every day. Instead, they call your ID number for attendance.
Your ID number represents all your stored information.
Now relate this to how we upload images to Cloudinary using MERN stack:
- Cloudinary = School office (stores actual image)
- MongoDB = Classroom register
- Image URL = Student ID number
Cloudinary stores the actual image. MongoDB stores only the reference link.
This is the professional way to upload images in modern applications.
How the Image Upload Flow Works
- User selects image in React frontend
- React sends image to Express backend
- Multer processes the file
- Backend uploads image to Cloudinary
- Cloudinary returns a secure URL
- MongoDB stores that URL
Frontend: How React Uploads Images
The image upload process starts from the frontend.
In React, we capture the file from an input field and send it using FormData.
const formData = new FormData();
formData.append("image", file);
await axios.post("/api/images/upload", formData);
Why use FormData?
Because images cannot be sent as normal JSON. They must be sent as multipart/form-data.
The key name "image" must match the backend field name.
This request goes to your Express backend.
Backend Step 1: Multer Middleware
Express cannot handle file uploads by default. Multer reads file data and attaches it to req.file.
const multer = require("multer");
const upload = multer({
storage: multer.memoryStorage(),
limits: { fileSize: 5 * 1024 * 1024 }
});
We use memory storage because we do not want to store files locally. We immediately send them to Cloudinary.
Backend Step 2: Cloudinary Service Layer
Instead of writing Cloudinary logic inside the controller, we separate it into a service.
cloudinary.config({
cloud_name: process.env.CLOUD_NAME,
api_key: process.env.API_KEY,
api_secret: process.env.API_SECRET
});
This keeps our architecture clean and professional.
Backend Step 3: Controller
const uploadImage = async (req, res) => {
if (!req.file) return res.status(400).json({ error: "No file" });
const imageUrl = await uploadToCloudinary(req.file.buffer);
await Image.create({ imageUrl });
res.status(201).json({ success: true });
};
The controller connects Multer, Cloudinary service, and MongoDB.
Backend Step 4: Route
router.post("/upload", upload.single("image"), uploadImage);
The complete flow becomes:
Route → Multer → Controller → Service → Cloudinary → MongoDB
Frequently Asked Questions
1. Can I upload images directly from React to Cloudinary?
Yes, but it is safer to upload through backend so your API_SECRET remains hidden.
2. Why should I not store images inside MongoDB?
MongoDB is optimized for structured data, not large binary files like images.
3. Is Cloudinary free?
Yes, Cloudinary offers a generous free tier suitable for learning and small projects.
4. What does Multer do?
Multer processes file uploads and makes image data available in req.file.
5. Is this method production-ready?
Yes. This is the industry-standard way to upload images to Cloudinary using MERN stack.
Final Thoughts
Uploading images correctly is not just about making it work — it’s about making it scalable.
- Do not store images inside MongoDB.
- Do not depend on local storage for production.
- Upload images to Cloudinary.
- Store only the image URL in MongoDB.
When you upload images to Cloudinary using MERN stack properly, your application becomes secure, scalable, and production-ready.
Understand the architecture first. Code becomes easy after that.
Related Articles
If you are improving your development skills, these guides will help you.
- API Not Working? Here's Exactly How I Debug Every Full-Stack Bug
- Why Your Child Component Isn't Updating Parent State in React (And How to Fix It)
- Building a Backend from Scratch at Work — Bugs, TypeScript Struggles, and Finally a Green CI Build
- How to Plan Projects Before Coding | Developer Guide (2026)
Comments
Post a Comment