Prerequisites
Before you start using Multer, ensure you have the following installed:
- Node.js: Install the latest version from Node.js official website.
- npm: Comes bundled with Node.js.
- Basic knowledge of Node.js and Express.js: Familiarity with building basic APIs.
Features of npm Multer
- Flexible Storage Options:
- DiskStorage: Stores files on disk.
- MemoryStorage: Stores files in memory as buffers.
- File Validation:
- Allows filtering files based on type and size.
- Error Handling:
- Provides mechanisms to catch and handle file upload errors gracefully.
- Customizable:
- Configure storage locations, filenames, and field names to match your application’s needs.
- Supports Single and Multiple Uploads:
- Handle individual or multiple file uploads with ease.
Project Setup
Before we start using Multer, we need to set up a basic Node.js project. If you already have a project, you can skip this part. Otherwise, follow these steps to create a new Node.js project from scratch.
Step 1: Initialize a New Node.js Project
First, open your terminal or command prompt & navigate to the folder where you want to create your project. Once you’re in the desired folder, run the following command to initialize a new Node.js project:
npm init -y
This command creates a `package.json` file in your project directory. The `-y` flag automatically fills in the default values for the project, so you don’t have to manually answer the setup questions.
Step 2: Install Required Dependencies
Next, we need to install the necessary packages for our project. For now, we’ll install Express (a popular Node.js framework) & Multer (the file upload middleware). Run the following command in your terminal:
npm install express multer
This installs both Express & Multer in your project & adds them to the `dependencies` section of your `package.json` file.
Step 3: Create the Basic Project Structure
Now, let’s create the basic structure of our project. In the root folder of your project, create the following files:
1. `app.js`: This will be the main file where we write our server code.
2. `uploads/`: This is a folder where Multer will store the uploaded files. Create this folder manually.
Your project structure should look like this:
project-folder/
│
├── node_modules/
├── uploads/
├── package.json
└── app.js
Step 4: Write the Basic Server Code
Open the `app.js` file & add the following code to set up a basic Express server:
// Importing required modules
const express = require('express');
const multer = require('multer');
const path = require('path');
// Initialize Express app
const app = express();
// Set up a basic route
app.get('/', (req, res) => {
res.send('Welcome to the file upload example!');
});
// Start the server
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
Let’s see what this code does:
1. We import the required modules: `express`, `multer`, & `path`.
2. We initialize an Express app using `express()`.
3. We create a basic route (`/`) that sends a welcome message when accessed.
4. Finally, we start the server on port 3000.
Step 5: Test the Server
To make sure everything is working, run the following command in your terminal:
node app.js
Open your browser & go to `http://localhost:3000`. You should see the message: "Welcome to the file upload example!"
Installation
Multer is a middleware specifically designed to handle `multipart/form-data`, which is the encoding type used for file uploads. It simplifies the process of managing file uploads in Node.js applications. Let’s understand how to configure & use Multer in your project.
Step 1: Understanding Multer Configuration
Multer requires some configuration to work properly. The most important part is setting up storage. Storage defines where & how the uploaded files will be stored. Multer provides two main options for storage:
1. Disk Storage: Files are stored on the server’s disk.
2. Memory Storage: Files are stored in memory as `Buffer` objects (useful for processing files without saving them).
For most use cases, Disk Storage is preferred. Let’s configure it.
Step 2: Configuring Disk Storage
To configure disk storage, we use Multer’s `diskStorage` method. This method allows us to specify:
- The destination folder where files will be saved.
- The filename for the uploaded file.
Let’s see how to set it up:
// Importing required modules
const express = require('express');
const multer = require('multer');
const path = require('path');
// Initialize Express app
const app = express();
// Configure Disk Storage
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/'); // Files will be saved in the 'uploads' folder
},
filename: (req, file, cb) => {
// Create a unique filename using the current timestamp & original file name
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() 1e9);
cb(null, uniqueSuffix + '-' + file.originalname);
},
});
// Initialize Multer with the storage configuration
const upload = multer({ storage: storage });
// Set up a basic route
app.get('/', (req, res) => {
res.send('Welcome to the file upload example!');
});
// Start the server
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
In this Code:
1. `destination`: This function determines where the uploaded files will be stored. In this case, files are saved in the `uploads/` folder.
2. `filename`: This function generates a unique filename for each uploaded file. We combine the current timestamp, a random number, & the original file name to ensure uniqueness.
3. `upload`: This is the Multer middleware initialized with the `storage` configuration.
Step 3: Testing Multer Configuration
To test if Multer is working, let’s create a route for file uploads. Add the following code to your `app.js` file:
// Route for uploading a single file
app.post('/upload', upload.single('file'), (req, res) => {
// 'file' is the name of the file input field in the form
if (!req.file) {
return res.status(400).send('No file uploaded.');
}
res.send('File uploaded successfully!');
});
In this Code:
1. `upload.single('file')`: This middleware handles the upload of a single file. The `'file'` argument corresponds to the name of the file input field in the HTML form.
2. `req.file`: This object contains information about the uploaded file, such as its path, size, & original name.
3. If no file is uploaded, the server responds with a `400 Bad Request` error.
Step 4: Testing the File Upload
To test the file upload, you can use tools like Postman or create a simple HTML form. For example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>File Upload</title>
</head>
<body>
<form action="http://localhost:3000/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="file" />
<button type="submit">Upload</button>
</form>
</body>
</html>
Save this HTML file & open it in your browser. Select a file & click "Upload". If everything is set up correctly, you should see the message: "File uploaded successfully!" & the file will be saved in the `uploads/` folder.
File Upload with Multer
Now that we’ve set up Multer & configured disk storage, let’s explore how to upload files using Multer. We’ll start with uploading a single file & then move to more advanced features like file filtering & size limits.
Step 1: Uploading a Single File
Uploading a single file is the most basic use case for Multer. We’ve already created a route for this in the previous section, but let’s break it down further & add some enhancements.
Let’s take a look at the complete code for uploading a single file:
// Importing required modules
const express = require('express');
const multer = require('multer');
const path = require('path');
// Initialize Express app
const app = express();
// Configure Disk Storage
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/'); // Files will be saved in the 'uploads' folder
},
filename: (req, file, cb) => {
// Create a unique filename using the current timestamp & original file name
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() 1e9);
cb(null, uniqueSuffix + '-' + file.originalname);
},
});
// Initialize Multer with the storage configuration
const upload = multer({ storage: storage });
// Set up a basic route
app.get('/', (req, res) => {
res.send('Welcome to the file upload example!');
});
// Route for uploading a single file
app.post('/upload', upload.single('file'), (req, res) => {
// 'file' is the name of the file input field in the form
if (!req.file) {
return res.status(400).send('No file uploaded.');
}
// Send a success response with file details
res.send({
message: 'File uploaded successfully!',
fileDetails: {
filename: req.file.filename,
path: req.file.path,
size: req.file.size,
mimetype: req.file.mimetype,
},
});
});
// Start the server
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
In this Code:
1. `upload.single('file')`: This middleware handles the upload of a single file. The `'file'` argument corresponds to the name of the file input field in the HTML form.
2. `req.file`: This object contains information about the uploaded file, such as:
- `filename`: The name of the file saved on the server.
- `path`: The full path to the file on the server.
- `size`: The size of the file in bytes.
- `mimetype`: The MIME type of the file (e.g., `image/jpeg`, `application/pdf`).
3. If no file is uploaded, the server responds with a `400 Bad Request` error.
4. If the file is uploaded successfully, the server sends a response with the file details.
Step 2: Testing the File Upload
To test this, you can use the same HTML form we created earlier or use a tool like Postman. Let’s take a look at the HTML form again for reference:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>File Upload</title>
</head>
<body>
<form action="http://localhost:3000/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="file" />
<button type="submit">Upload</button>
</form>
</body>
</html>
Upload a file using this form, & you should see a response like this:
{
"message": "File uploaded successfully!",
"fileDetails": {
"filename": "1698765432100-123456789-file.jpg",
"path": "uploads/1698765432100-123456789-file.jpg",
"size": 1024,
"mimetype": "image/jpeg"
}
}
Step 3: Adding File Filtering
Sometimes, you may want to restrict the types of files that can be uploaded. For example, you might only allow images or PDFs. Multer makes this easy with its `fileFilter` option.
Let’s see how to add file filtering:
// Configure File Filtering
const fileFilter = (req, file, cb) => {
// Allow only image files
if (file.mimetype.startsWith('image/')) {
cb(null, true); // Accept the file
} else {
cb(new Error('Only image files are allowed!'), false); // Reject the file
}
};
// Initialize Multer with storage & file filtering
const upload = multer({
storage: storage,
fileFilter: fileFilter,
});
In this Code:
1. `fileFilter`: This function checks the MIME type of the uploaded file. If the file is an image (MIME type starts with `image/`), it’s accepted. Otherwise, an error is thrown.
2. `cb(null, true)`: This callback accepts the file.
3. `cb(new Error(), false)`: This callback rejects the file & sends an error message.
Now, if you try to upload a non-image file, you’ll get an error: "Only image files are allowed!"
Steps to Create Application and Installing Package
Step 1: Initialize a Node.js Application
Run the following commands to create a new Node.js project:
mkdir multer-demo
cd multer-demo
npm init -y
This creates a new directory and initializes it as a Node.js project.
Step 2: Install Dependencies
Install the required packages:
npm install express multer body-parser
- Express: Framework to create the server.
- Multer: Middleware for file uploads.
- Body-parser: Parses incoming request bodies.
Step 3: Set Up Multer in Express Application
Create a file named app.js and add the following code:
const express = require('express');
const multer = require('multer');
const path = require('path');
const app = express();
// Set up storage engine
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/');
},
filename: (req, file, cb) => {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname));
}
});
// Initialize multer
const upload = multer({
storage: storage,
limits: { fileSize: 5 * 1024 * 1024 }, // 5MB limit
fileFilter: (req, file, cb) => {
const fileTypes = /jpeg|jpg|png|gif/;
const extName = fileTypes.test(path.extname(file.originalname).toLowerCase());
const mimeType = fileTypes.test(file.mimetype);
if (extName && mimeType) {
return cb(null, true);
} else {
cb(new Error('Only images are allowed!'));
}
}
});
// Middleware
app.use(express.static('public'));
app.use(express.json());
// Route for file upload
app.post('/upload', upload.single('file'), (req, res) => {
if (req.file) {
res.status(200).send({ message: 'File uploaded successfully', file: req.file });
} else {
res.status(400).send({ error: 'File upload failed' });
}
});
// Error handling
app.use((err, req, res, next) => {
if (err instanceof multer.MulterError) {
res.status(500).send({ error: err.message });
} else {
res.status(500).send({ error: 'An unknown error occurred' });
}
});
// Start the server
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
Step 4: Create Uploads Directory
Create a folder named uploads in your project directory. This is where the uploaded files will be stored.
Step 5: Test the Application
- Run the server:
node app.js - Use tools like Postman or a frontend form to send a POST request to http://localhost:3000/upload with a file.
Dependencies
- Express: Used to create the server and handle routes.
- Multer: Handles file uploads.
- Path: Built-in Node.js module for handling file paths.
- Body-parser: Parses incoming JSON and form data (if required).
Output Demonstration
Example Input:
Example Response:
{
"message": "File uploaded successfully",
"file": {
"fieldname": "file",
"originalname": "image.jpg",
"encoding": "7bit",
"mimetype": "image/jpeg",
"destination": "uploads/",
"filename": "file-1672948027321.jpg",
"path": "uploads/file-1672948027321.jpg",
"size": 123456
}
}
This confirms the file upload was successful, and it provides details about the uploaded file.
Uploading Multiple Files
In many applications, you might need to upload multiple files at once. For example, a user might want to upload multiple images for a gallery or several documents for a project. Multer makes it easy to handle multiple file uploads with its `array` or `fields` methods.
Step 1: Uploading Multiple Files Using `array`
The `array` method allows you to upload multiple files using the same field name. For example, if your HTML form has multiple file inputs with the same name, you can use `array` to handle them.
Let’s take a look at the complete code for uploading multiple files:
// Importing required modules
const express = require('express');
const multer = require('multer');
const path = require('path');
// Initialize Express app
const app = express();
// Configure Disk Storage
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/'); // Files will be saved in the 'uploads' folder
},
filename: (req, file, cb) => {
// Create a unique filename using the current timestamp & original file name
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() 1e9);
cb(null, uniqueSuffix + '-' + file.originalname);
},
});
// Initialize Multer with the storage configuration
const upload = multer({ storage: storage });
// Set up a basic route
app.get('/', (req, res) => {
res.send('Welcome to the file upload example!');
});
// Route for uploading multiple files
app.post('/upload-multiple', upload.array('files', 5), (req, res) => {
// 'files' is the name of the file input field in the form
// The second argument (5) is the maximum number of files allowed
if (!req.files || req.files.length === 0) {
return res.status(400).send('No files uploaded.');
}
// Send a success response with file details
res.send({
message: 'Files uploaded successfully!',
fileDetails: req.files.map(file => ({
filename: file.filename,
path: file.path,
size: file.size,
mimetype: file.mimetype,
})),
});
});
// Start the server
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
In this Code:
1. `upload.array('files', 5)`: This middleware handles the upload of multiple files. The `'files'` argument corresponds to the name of the file input field in the HTML form. The second argument (`5`) specifies the maximum number of files allowed.
2. `req.files`: This is an array containing information about all the uploaded files. Each file object has properties like `filename`, `path`, `size`, & `mimetype`.
3. If no files are uploaded, the server responds with a `400 Bad Request` error.
4. If the files are uploaded successfully, the server sends a response with the details of all uploaded files.
Step 2: Testing the Multiple File Upload
To test this, you can use the following HTML form:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Multiple File Upload</title>
</head>
<body>
<form action="http://localhost:3000/upload-multiple" method="POST" enctype="multipart/form-data">
<input type="file" name="files" multiple />
<button type="submit">Upload</button>
</form>
</body>
</html>
In this form:
- The `name` attribute of the file input is set to `files` (matching the field name in the Multer middleware).
- The `multiple` attribute allows users to select multiple files at once.
Upload multiple files using this form, & you should see a response like this:
{
"message": "Files uploaded successfully!",
"fileDetails": [
{
"filename": "1698765432100-123456789-file1.jpg",
"path": "uploads/1698765432100-123456789-file1.jpg",
"size": 1024,
"mimetype": "image/jpeg"
},
{
"filename": "1698765432101-123456789-file2.png",
"path": "uploads/1698765432101-123456789-file2.png",
"size": 2048,
"mimetype": "image/png"
}
]
}
Step 3: Uploading Multiple Files with Different Field Names Using `fields`
If your form has multiple file inputs with different names, you can use the `fields` method. Here’s how:
// Route for uploading multiple files with different field names
app.post('/upload-fields', upload.fields([
{ name: 'avatar', maxCount: 1 }, // Accepts 1 file with the field name 'avatar'
{ name: 'gallery', maxCount: 5 }, // Accepts up to 5 files with the field name 'gallery'
]), (req, res) => {
if (!req.files) {
return res.status(400).send('No files uploaded.');
}
// Send a success response with file details
res.send({
message: 'Files uploaded successfully!',
fileDetails: {
avatar: req.files['avatar'] ? req.files['avatar'][0] : null,
gallery: req.files['gallery'] || [],
},
});
});
In this Code:
1. `upload.fields`: This middleware handles multiple file inputs with different field names. Each field is specified as an object with `name` & `maxCount` properties.
2. `req.files`: This object contains arrays of files for each field name. For example, `req.files['avatar']` contains the files uploaded under the `avatar` field.
Frequently Asked Questions
What is the purpose of Multer in Node.js?
Multer is a middleware that simplifies handling multipart/form-data, especially for file uploads in Node.js applications.
How can I restrict file types in Multer?
You can use the fileFilter option to define allowed file types and reject others based on mimetype or file extensions.
Where are uploaded files stored in Multer?
Uploaded files are stored in the location specified by the destination field in the storage configuration. By default, it’s a local directory like uploads/.
Conclusion
Multer is a powerful and flexible middleware for handling file uploads in Node.js applications. It provides customizable options to manage file storage and validation efficiently. With Multer, you can build robust APIs for file uploads in your projects.