# Express File Upload with Multer in Node.js

By Atta Ur Rehman Shah (https://attacomsian.com/about). Published Sep 24, 2019, updated Oct 1, 2022. Topics: Node.js, Express.js.
Canonical URL: https://attacomsian.com/blog/express-file-upload-multer

> A step-by-step guide to uploading single and multiple files with Express.js and Multer in Node.js.

In an [earlier article](https://attacomsian.com/blog/uploading-files-nodejs-express), I explained how to upload files in Node.js and Express with `express-fileupload` middleware.

Today, we will go through another popular middleware called [Multer](https://www.npmjs.com/package/multer) for handling single and multiple file uploads with Express and Node.js. We will save the uploaded files on the local file system.

## What is Multer?

As I said earlier, Multer is an Express middleware for handling `multipart/form-data` requests. When a user uploads a file to the server, the browser automatically encodes the request as `multipart/form-data`. Multer makes it easy to handle such a request on the server.

## Project Setup

Let us create a new directory for our demo project and switch to it by typing the command following:

```bash
$ mkdir express-multer && cd express-multer
```

Next, create the `package.json` file by running the following command:

```bash
$ npm init -y
```

Now install Multer, Express, and other required dependencies:

```bash
$ npm install express multer body-parser cors morgan --save
```

## Basic Express Server

Let us now create a basic Express server. First of all, create an `index.js` file:

```bash
$ touch index.js
```

Copy and paste the following code into it to initialize all the modules and start the Express app:

<p class="file-desc"><span>index.js</span></p>

```javascript
const express = require('express')
const multer = require('multer')
const cors = require('cors')
const bodyParser = require('body-parser')
const morgan = require('morgan')

// create an express app
const app = express()

// upload file path
const FILE_PATH = 'uploads'

// configure multer
const upload = multer({
  dest: `${FILE_PATH}/`
})

// enable CORS
app.use(cors())

// add other middleware
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(morgan('dev'))

// start the app
const port = process.env.PORT || 3000

app.listen(port, () => console.log(`App is listening on port ${port}.`))
```

The above code configures Multer to accept `multipart/form-data` file upload requests and save them to the `uploads` folder, enables Cross-Original Resource Sharing (CORS), and starts the Express server at port `3000`.

## Upload Single File

Let us create our first route in the Express application to allow users to upload their profile images:

```javascript
app.post('/upload-avatar', upload.single('avatar'), async (req, res) => {
  try {
    const avatar = req.file

    // make sure the file is available
    if (!avatar) {
      res.status(400).send({
        status: false,
        data: 'No file is selected.'
      })
    } else {
      // send response
      res.send({
        status: true,
        message: 'File is uploaded.',
        data: {
          name: avatar.originalname,
          mimetype: avatar.mimetype,
          size: avatar.size
        }
      })
    }
  } catch (err) {
    res.status(500).send(err)
  }
})
```

The above function receives an HTTP POST request. `upload.single('avatar')` is Multer middleware that accepts a single file with the field name `avatar`, uploads it to the destination folder, and adds a `file` property to the `req` object.

We can access the uploaded file using the `req.file` property. It has the following important information:

* `fieldname` &mdash; The name of the field used in the form
* `originalname` &mdash; The name of the file on the user's computer
* `encoding` &mdash; Encoding type of the file
* `mimetype` &mdash; Mime type of the file
* `size` &mdash; The size of the file in bytes

We simply use these properties in the single file upload route to return the uploaded file details.


## Upload Multiple Files

Let us add another route. This time for uploading multiple files at once:

```javascript
app.post('/upload-photos', upload.array('photos', 8), async (req, res) => {
  try {
    const photos = req.files

    // check if photos are available
    if (!photos) {
      res.status(400).send({
        status: false,
        data: 'No photo is selected.'
      })
    } else {
      let data = []

      // iterate over all photos
      photos.map(p =>
        data.push({
          name: p.originalname,
          mimetype: p.mimetype,
          size: p.size
        })
      )

      // send response
      res.send({
        status: true,
        message: 'Photos are uploaded.',
        data: data
      })
    }
  } catch (err) {
    res.status(500).send(err)
  }
})
```

Uploading multiple files with Multer is similar to a single file upload with a few changes. The Multer middleware now accepts an array of files as input, with a maximum of 8 files at once. The field name is also changed to `photos`.

## Testing the Application

Start the Express application by running the following command in your terminal from the root directory:

```bash
$ node index.js
```

It will start the application at port `3000`. Let us use [Postman](https://www.getpostman.com/) for sending HTTP `multipart/form-data` requests:

### Single File

![Multer Single File Upload](https://statics.attacomsian.com/gims/826ec99d-af66-411f-9722-bf9dc97579db.png)

### Multiple Files

![Multer Multiple Files Upload](https://statics.attacomsian.com/gims/48e273e4-2836-4a64-9e4e-72f038dbabbc.png)

## File Size Limit

If you want to limit the file size, add the `limits` property to the object that is passed to `multer()`:

```javascript
const upload = multer({
  dest: `${FILE_PATH}/`,
  limits: {
    files: 5, // allow up to 5 files per request,
    fileSize: 2 * 1024 * 1024 // 2 MB (max file size)
  }
})
```

## Filter File Type

Sometimes we want to allow users to upload images only. You can easily limit the file types by using the `fileFilter` property:

```javascript
const upload = multer({
  dest: `${FILE_PATH}/`,
  limits: {
    files: 5, // allow up to 5 files per request,
    fileSize: 2 * 1024 * 1024 // 2 MB (max file size)
  },
  fileFilter: (req, file, cb) => {
    // allow images only
    if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) {
      return cb(new Error('Only image are allowed.'), false)
    }
    cb(null, true)
  }
})
```

> **Source code:** Download the complete source code from [GitHub](https://github.com/attacomsian/code-examples/tree/master/nodejs/express-multer) available under MIT license.

## Conclusion

That's all folks for today. You have learned how to upload files using Express and Multer in Node.js. Multer is an easy-to-use Express middleware for handling `multipart/form-data` requests. 

Check out the [official documentation](https://github.com/expressjs/multer) for more configuration options.
