Upload and Retrieve Image on MongoDB using Mongoose
Last Updated :
10 Jun, 2025
Managing images efficiently is a common requirement in modern web applications. MongoDB with Mongoose provides a great method of storing and retrieving images within your database. In this tutorial, we will demonstrate how to upload and fetch images using MongoDB and Mongoose in a Node.js application with simple steps, code examples, and best practices.
Why Store Images in MongoDB?
- Unified data management: Store both data and images in one place without external storage dependencies.
- Scalability: MongoDB handles large volumes of data and provides fast retrieval.
- Flexibility: Mongoose schemas allow you to define image storage as binary data, making integration seamless.
Step 1: Install Required Packages
Run the following commands to install essential packages. ExpressJS allows us to set up middleware to respond to HTTP Requests.
npm install express --save
The module "body-parser" enables reading (parsing) HTTP-POST data.
npm install body-parser --save
Mongoose is a MongoDB client library providing object modeling for use in an asynchronous environment. Mongoose supports both promises and callbacks.
npm install mongoose --save
Multer is nodejs middleware used for uploading files.
npm install multer --save
Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env.
npm install dotenv --save
EJS (Embedded JavaScript) is a templating engine for nodejs. This engine helps to create an HTML page via templates with minimal code.
npm install ejs --save
nodemon is a development tool that re-launches the node application when file updates in the code directory are noticed. It enhances the development process while working on node-based applications. Since this is a development tool and not part of our application code, we use `--save-dev` when installing this module:
npm install nodemon --save-dev
Step 2: Project Structure
Project StructureNow let's start coding! To upload an image and retrieve an image by MongoDB using Mongoose, follow each of the steps below one by one.
Create a .env
file to securely store your MongoDB connection string:
MONGO_URL="mongodb://127.0.0.1:27017/imagesInMongoApp"
PORT=3000
Step 4: Build the Express Server (app.js
)
Set up your Express server to handle file uploads and serve pages
var express = require('express')
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose')
var imgSchema = require('./model.js');
var fs = require('fs');
var path = require('path');
app.set("view engine", "ejs");
require('dotenv').config();
mongoose.connect(process.env.MONGO_URL)
.then(console.log("DB Connected"))
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
var multer = require('multer');
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads')
},
filename: (req, file, cb) => {
cb(null, file.fieldname + '-' + Date.now())
}
});
var upload = multer({ storage: storage });
app.get('/', (req, res) => {
imgSchema.find({})
.then((data, err)=>{
if(err){
console.log(err);
}
res.render('imagepage',{items: data})
})
});
app.post('/', upload.single('image'), (req, res, next) => {
var obj = {
name: req.body.name,
desc: req.body.desc,
img: {
data: fs.readFileSync(path.join(__dirname + '/uploads/' + req.file.filename)),
contentType: 'image/png'
}
}
imgSchema.create(obj)
.then ((err, item) => {
if (err) {
console.log(err);
}
else {
// item.save();
res.redirect('/');
}
});
});
var port = process.env.PORT || '3000'
app.listen(port, err => {
if (err)
throw err
console.log('Server listening on port', port)
})
Step 5: Define Mongoose Schema to Store Images (model.js
)
Once we have established a connection to our database and required all the necessary packages, we can now begin defining our server-side logic. So for storing an image in MongoDB, we need to create a schema with mongoose.
For that create the file `model.js` file and define the schema. The key point here is that our data type for the image is a Buffer which lets us save our image as data in the form of arrays.
var mongoose = require('mongoose');
var imageSchema = new mongoose.Schema({
name: String,
desc: String,
img:
{
data: Buffer,
contentType: String
}
});
module.exports = mongoose.model('Image', imageSchema);
Step 6: Create Image Upload Page (views/imagePage.ejs
)
This is the HTML template for the "upload page". Notice that the src parameter for the <img> is not a typical URL. This format enables displaying the image stored in binary format in the Mongo database, and we convert it to base64 so that the browser can render it.
Add the following code to the `views/imagePage.ejs`:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Image Uploading</title>
</head>
<body>
<h1>To Upload Image on mongoDB</h1>
<hr />
<div>
<form action="/" method="POST" enctype="multipart/form-data">
<div>
<label for="name">Image Title</label>
<input
type="text"
id="name"
placeholder="Name"
value=""
name="name"
required
/>
</div>
<div>
<label for="desc">Image Description</label>
<textarea
id="desc"
name="desc"
value=""
rows="2"
placeholder="Description"
required
>
</textarea>
</div>
<div>
<label for="image">Upload Image</label>
<input type="file" id="image" name="image" value="" required />
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>
</div>
<hr />
<h1>Uploaded Images</h1>
<div>
<% items.forEach(function(image) { %>
<div>
<div>
<img
src="data:image/<%=image.img.contentType%>;base64,
<%=image.img.data.toString('base64')%>"
/>
<div>
<h5><%= image.name %></h5>
<p><%= image.desc %></p>
</div>
</div>
</div>
<% }) %>
</div>
</body>
</html>
Step 7: Start Your Server
Use nodemon to start your development server:
npx nodemon app.js
Step 8: Test Your Application
Open your browser and visit:
http://localhost:3000/
- Enter a name and select an image file to upload.
- Submit the form to upload the image.
- The uploaded images will display below the form in real-time.
Output
Open your browser to http://localhost:3000/ . You should now see:
Benefits of This Approach
- Image storage inside MongoDB keeps your data centralized.
- Mongoose Buffer data type efficiently stores binary images.
- EJS templating enables dynamic rendering without complex frontend frameworks.
- Multer middleware simplifies file upload handling.
- Automatic cleanup of temporary files after upload keeps your server clean.
Conclusion
Uploading and retrieving images in MongoDB using Mongoose is straightforward and efficient with this setup. It uses Node.js tools like Express, Multer, and EJS to create a full-stack solution ideal for many web apps. This approach keeps your data in one place and simplifies image management. Start implementing this today to build scalable, user-friendly applications with seamless image handling!