Files that are uploaded by users are usually submitted through a form and encoded as multipart/form-data. In this tutorial, we’ll show you how to handle and process uploaded files in Node.js with the help of Express.js and Multer.

Multer is a middleware for Express.js and Node.js that is capable of handling file uploads, more specifically data that are encoded as multipart/form-data.

We’ll get started by first creating an empty directory and running npm init -y to create a package.json file that lists all the project dependencies.

mkdir node-app
cd node-app
npm init -y

Next, install Express and Multer using the node package manager (npm):

npm install --save express multer

Now create a file where you’ll write the code to handle file uploads. For this tutorial, we’ll call this file upload.js.

touch upload.js

Handling file uploads using Multer and Express

Let’s get started by importing the Multer and Express modules, creating the Express app, and configuring Multer.

// Import the required modules
const express = require('express');
const multer = require('multer');
// Create Express app
const app = express();
// Configure Multer
const upload = multer({
    dest: 'uploads/'
});

In the code above, we used the “dest” option in Multer’s configuration to define the destination where the files will be upload.

There are a few other options that Multer offers such as the following:

limitsSet the limits of the file upload. You can set the maximum number of allowed files, maximum file size, and other limitations.
fileFilterWith this option, you can control which files should be accepted or rejected.
preservePathKeep the full path of files instead of just the base name. If the value is true, the file’s extension will be preserved.

Uploading a Single File

First, let’s take a look at how we can upload a single file. In your HTML file where you wish to add the upload functionality, insert the following code:

<form action="/single-file-upload" method="post" enctype="multipart/form-data">
    <input type="file" name="my-file"/>
    <input type="submit" value="Upload" />
</form>

Generally, multipart/form-data content-type is used when uploading files via a foorm. This is why we have added the enctype="multipart/form-data" attribute to the form.

Next, go back to the upload.js to define a route that will handle the HTTP POST request submitted by the form.

app.post('/single-file-upload', upload.single('my-file'), (req, res, next) => {
    // Display JSON data of uploaded file
    console.log(req.file);
    res.send("File upload successful");
});

In the above code, you pass the name of the HTML file input field to the upload.single() function. In this case, we named it as “my-file” in HTML.

The req.file object provides the following information:

fieldnameName of the field in the form
originalnameName of the uploaded file on the request body
encodingEncoding of the uploaded file
mimetypeMime type of the file. This describes the file type.
sizeThe size of the uploaded file in bytes
destinationThe directory of the saved file.
filenameThe name of the file which is saved into the destination. This will be a random string without the extension by default.
pathThis is the full path to the uploaded file.
bufferA Buffer of the uploaded file which is stored in the memory.

Here is an example of a req.file object:

{ 
    fieldname: 'my-file',
    originalname: '4.jpg',
    encoding: '7bit',
    mimetype: 'image/jpeg',
    destination: 'uploads/',
    filename: '73c3890e21914c3e4428e8bc3571c252',
    path: 'uploads/73c3890e21914c3e4428e8bc3571c252',
    size: 110533 
}

Next, let’s start the server.

app.listen(3000, () => {
    console.log('Server is listening on port 3000');
});

Now open your command line and run node upload.js to start the server. Make sure that you’re in the same directory where the upload.js file was created. If the server is up and running, it should output the following message:

Server is listening on port3000

Similarly, if you open a browser and head to localhost:3000, it will display the above message.

Now that we’re done, open the HTML page in a browser and upload a file. If you check your uploads folder, the uploaded file should be stored there.

Uploading Multiple Files

You can also handle multiple file uploads using Multer. In your HTML file, add the following:

<form action="/multiple-file-upload" method="post" enctype="multipart/form-data">
    <input type="file" name="my-files" multiple/>
    <input type="submit" value="Upload" />
</form>

Next, create another route in upload.js to process multiple file uploads. You can use the upload.array() function to create a middleware to process multiple uploaded files. Note that if you are using this function, you may not be able to identify each image uniquely. It is suitable for a collection of files that do not need to be identified uniquely, such as a collection of product images uploaded to an online store.

app.post('/multiple-file-upload', upload.array('my-files', 10), (req, res, next) => {
    // Display JSON data of uploaded files
    console.log(req.files);
    res.send("Files uploaded successfully");
});

Optionally, you can also pass the maximum files limit to the upload.array() function to limit the number of files that can be uploaded. This will help you to avoid malicious uploads.

Open the HTML page in a browser and try uploading multiple files. You should now see all the files stored in the uploads directory on your server.

Uploading Multiple Files with Different File Input Fields

We can use the upload.fields() function to create middleware for files uploaded from multiple file input fields. These files will be identifiable uniquely by their field name. Also, an file input field can contain more than one file if required.

Let’s create a route handler to demonstrate this.

const middleware = upload.fields([ { name: 'my-file', maxCount: 1 }, { name: 'my-files', maxCount: 10 } ]);

app.post('/multiple-fields', middleware, (req, res) => {
    // Process my-file and my-files here
    console.log(req.files['my-file']);
    console.log(req.files['my-files']);

    res.send("File uploaded successfully");
})

Notice that for the field with a single upload, we set the maxCount to 1.

That’s all you have to do to handle single and multiple file uploads in Node.js with the help of Multer and Express.js. Should you face any issues, do not hesitate to let us know in the comments below.