Handle a File Upload in Node.js and Express with Multer
Last updated: January 10, 2023.
The Multer package for Node.js allows you to handle the uploading of a single or multiple files as well as additional form data.
We’ll use the following HTML form as an example, which contains a text input element and the opportunity for a user to upload one or more files:
<form>
<input type="text" name="file-name" id="name">
<input type="file" name="file" id="files" multiple>
<button type="submit">Submit</button>
</form>
Sticking with the frontend, we’ll now handle the submission of the form with JavaScript:
const form = document.querySelector('form');
form.addEventListener('submit', (e) => {
e.preventDefault();
// Prevents HTML handling submission
const name = document.getElementById("name");
const files = document.getElementById("files");
const formData = new FormData();
// Creates empty formData object
formData.append("name", name.value);
// Appends value of text input
for(let i =0; i < files.files.length; i++) {
formData.append("files", files.files[i]);
}
// Appends value(s) of file input
// Post data to Node and Express server:
fetch('http://127.0.0.1:5000/api', {
method: 'POST',
body: formData, // Payload is formData object
})
.then(res => res.json())
.then(data => console.log(data));
})
Now, on the backend, we’ll handle the request using a Node and Express server.
For our server, we’ll be relying on the express
, multer
and cors
libraries. So make sure to install these when setting up a new project in your chosen directory first:
npm init --y
npm i express multer cors
Multer works by intercepting an incoming request to the server.
To begin, you’ll want to specify a destination
property and a filename
property as values on multer.diskStorage()
, to set where the file will be saved and what name it will be saved under, respectively.
Then, set this as the value of the storage
property when calling multer
.
Finally, include this as the middleware on the incoming request path, making sure that the the string passing in to upload.array()
matches the reference given to the files when constructing the formData object on the frontend:
const express = require("express");
const multer = require('multer');
const cors = require('cors');
var app = express();
app.use(cors()); // Allows incoming requests from any IP
// Start by creating some disk storage options:
const storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, __dirname + '/uploads');
},
// Sets file(s) to be saved in uploads folder in same directory
filename: function (req, file, callback) {
callback(null, file.originalname);
}
// Sets saved filename(s) to be original filename(s)
})
// Set saved storage options:
const upload = multer({ storage: storage })
app.post("/api", upload.array("files"), (req, res) => {
// Sets multer to intercept files named "files" on uploaded form data
console.log(req.body); // Logs form body values
console.log(req.files); // Logs any files
res.json({ message: "File(s) uploaded successfully" });
});
app.listen(5000, function(){
console.log("Server running on port 5000");
});
After submitting the form, output in the console should look something like this:

Happy uploading!
Related links
- Multer npm page
- POST form data using JavaScript’s Fetch API
- How to Post Multiple Files with the Fetch API
- Web scraping in NodeJS with Puppeteer
- Build a Visitor Counter with JavaScript & Node.js
- How to Schedule Tasks in Node.js