In an earlier article, 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 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:

$ mkdir express-multer && cd express-multer

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

$ npm init -y

Now install Multer, Express, and other required dependencies:

$ 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:

$ touch index.js

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

index.js

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:

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 — The name of the field used in the form
  • originalname — The name of the file on the user's computer
  • encoding — Encoding type of the file
  • mimetype — Mime type of the file
  • size — 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:

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:

$ node index.js

It will start the application at port 3000. Let us use Postman for sending HTTP multipart/form-data requests:

Single File

Multer Single File Upload

Multiple Files

Multer Multiple Files Upload

File Size Limit

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

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:

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 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 for more configuration options.

✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.