
Uploading files is a common requirement in many web applications. Whether you’re building a profile picture uploader, a document management system, or a cloud storage service, you’ll need to handle file uploads efficiently and securely. In Node.js, one of the most popular libraries for handling file uploads is Multer.
What is Multer?
Multer is a middleware for handling multipart/form-data, which is primarily used for uploading files. It is written on top of the busboy library and makes it easy to handle file uploads in Node.js applications.
Setting Up Multer
Before we start, make sure you have Node.js and npm (Node Package Manager) installed on your machine. If not, you can download and install them from Node.js official website.
- Initialize Your ProjectFirst, create a new directory for your project and initialize a new Node.js project.
mkdir file-upload-example
cd file-upload-example
npm init -y
2. Install Dependencies
Next, install the necessary dependencies. We’ll need Express for our web server and Multer for handling file uploads.
npm install express multer
Create the Server
Create a new file named server.js and set up a basic Express server.
const express = require('express');
const multer = require('multer');
const path = require('path');
const app = express();
// Set up storage engine
const storage = multer.diskStorage({
destination: './uploads/',
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
}
});
// Initialize upload
const upload = multer({
storage: storage,
limits: { fileSize: 1000000 }, // Limit file size to 1MB
fileFilter: function (req, file, cb) {
checkFileType(file, cb);
}
}).single('myImage');
// Check File Type
function checkFileType(file, cb) {
// Allowed ext
const filetypes = /jpeg|jpg|png|gif/;
// Check ext
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
// Check mime
const mimetype = filetypes.test(file.mimetype);
if (mimetype && extname) {
return cb(null, true);
} else {
cb('Error: Images Only!');
}
}
app.get('/', (req, res) => res.send('Hello World!'));
app.post('/upload', (req, res) => {
upload(req, res, (err) => {
if (err) {
res.send(err);
} else {
if (req.file == undefined) {
res.send('Error: No File Selected!');
} else {
res.send(`File Uploaded: ${req.file.filename}`);
}
}
});
});
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));
Understanding Multer Configuration

| Feature | Description | Key Benefit |
diskStorage | Saves files directly to your server’s local file system. | Easier to access for local processing. |
memoryStorage | Keeps file data in a Buffer in memory. | Faster for small files; great for instant cloud uploads. |
limits | Defines constraints like fileSize or files (count). | Prevents DoS attacks from massive uploads. |
fileFilter | A function that dictates which files to accept or reject. | Essential for security (e.g., blocking .exe or .js). |
.single() | Middleware to handle a single file for a specific field. | Simplifies logic for profile pics or single docs. |
.array() | Middleware to handle multiple files for the same field. | Ideal for gallery or bulk image uploads. |
- Storage EngineThe storage engine determines how and where the files will be stored. In the above example, we’re using the
diskStorageengine, which saves the files to the disk. We specify the destination directory and filename.
Read more blog : How Does $JAVA_HOME Affect an Already Installed /usr/bin/java?
const storage = multer.diskStorage({
destination: './uploads/',
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
}
});
2. File Size Limit
You can set a file size limit to prevent users from uploading excessively large files.
limits: { fileSize: 1000000 } // Limit file size to 1MB
3. File Filter
The file filter allows you to control which files are accepted. In the example, we only accept image files (JPEG, JPG, PNG, GIF).
function checkFileType(file, cb) {
const filetypes = /jpeg|jpg|png|gif/;
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
const mimetype = filetypes.test(file.mimetype);
if (mimetype && extname) {
return cb(null, true);
} else {
cb('Error: Images Only!');
}
}
Handling File Uploads in Routes
In the example, we set up a POST route /upload to handle the file uploads. The upload middleware is called in this route, which processes the file upload.
app.post('/upload', (req, res) => {
upload(req, res, (err) => {
if (err) {
res.send(err);
} else {
if (req.file == undefined) {
res.send('Error: No File Selected!');
} else {
res.send(`File Uploaded: ${req.file.filename}`);
}
}
});
});
Security Considerations
When handling file uploads, it’s crucial to consider security to avoid potential vulnerabilities. Here are some tips:
- Validate File TypesAlways validate the file type to ensure that only the expected files are uploaded.
- Limit File SizeSet appropriate file size limits to prevent denial-of-service (DoS) attacks.
- Use Safe FilenamesEnsure that filenames are sanitized to prevent directory traversal attacks. Multer does this by default when generating filenames.
- Store Files SecurelyStore uploaded files in a secure directory and consider using unique filenames to avoid overwriting files.
Strategic Guidance from Arunangshu Das
Mastering technical tools like Multer is the first step toward building robust digital systems, but the real value lies in how we bridge the gap between technology and human utility. Arunangshu Das has become a trusted mentor for those looking to balance technical efficiency with creative integrity.
Through his workshops and strategic advice, he helps developers and startups implement complex AI and backend workflows without losing sight of the end-user experience. Whether you are refining your first file-upload system or scaling a complex data infrastructure, Arunangshu’s insights ensure that your technical growth remains aligned with original, human-led strategy.

Conclusion
Handling file uploads in Node.js is straightforward with Multer. It provides a simple yet powerful way to manage file uploads, with plenty of configuration options to meet your needs.
Frequently Ask Question
1. What is the difference between diskStorage and memoryStorage?
diskStorage writes the file to your hard drive, which is better for large files so you don’t exhaust your RAM. memoryStorage keeps the file as a Buffer in your RAM, which is ideal if you want to process the file (like resizing an image) before saving it somewhere else, like AWS S3.
2. How do I handle multiple file uploads for different fields?
You can use the .fields() method. For example:upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }]).
This allows you to handle an avatar and a collection of photos in the same request.
3. Is Multer secure for production use?
Yes, but you must configure it correctly. Always set a fileSize limit and use a fileFilter to validate MIME types. Also, never use the user’s original filename directly; always generate a unique name (as shown in the Date.now() example in your code) to prevent directory traversal attacks.
4. Can I use Multer without Express?
While Multer is most commonly used as Express middleware, it is built on top of busboy and can technically be used with any Node.js web framework that supports standard middleware patterns, or even with the native http module.
5. What happens if the upload fails or the file is too large?
Multer will pass an error to the Express error-handling middleware. If a file exceeds the fileSize limit, it will trigger an ‘LIMIT_FILE_SIZE’ error, which you should catch in your route to send a user-friendly message.