Skip to main content

Command Palette

Search for a command to run...

Handling File Uploads in Express with Multer

Updated
3 min readView as Markdown
Handling File Uploads in Express with Multer

When you send text through a web form, Express can handle it easily with its built-in JSON parser. But files—like images, PDFs, or videos—are much heavier and more complex. They aren't sent as simple strings; they are sent as Multipart/form-data.

Standard Express doesn't know how to "read" these massive chunks of data. To handle them without crashing your server, you need a specialized middleware called Multer.

1. Why do we need Middleware for Files?

When a user uploads a file, the browser breaks that file into many small chunks and streams them to the server. If the server tried to read the whole file into its memory at once, it would run out of RAM and crash.

Multer acts as a traffic controller. It:

  1. Intersects the incoming "multipart" request.

  2. Processes the file chunks.

  3. Saves them to a destination (like a folder on your server).

  4. Adds a file object to the req (request) so you can access the file's details in your code.

2. Setting Up Multer

First, install it: npm install multer.

In its simplest form, you just tell Multer where to put the files.

const express = require('express');
const multer  = require('multer');
const upload = multer({ dest: 'uploads/' }); // Files will go here

const app = express();

3. Handling a Single File Upload

To handle a single file (like a profile picture), you use the upload.single('fieldName') middleware. The string you pass must match the name attribute in your HTML form.

app.post('/profile', upload.single('avatar'), (req, res) => {
  // req.file contains information about the uploaded file
  console.log(req.file); 
  res.send('File uploaded successfully!');
});

4. Handling Multiple File Uploads

If you are building a gallery or allowing users to upload several documents at once, use upload.array().

app.post('/photos', upload.array('gallery', 5), (req, res) => {
  // req.files is an array of file objects
  console.log(`Uploaded ${req.files.length} files.`);
  res.send('All files uploaded!');
});

5. Storage Configuration: Naming Your Files

By default, Multer gives files random names with no extensions (like 8e9f2...). To keep the original filename and extension, you need to use DiskStorage.

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/');
  },
  filename: function (req, file, cb) {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    cb(null, file.fieldname + '-' + uniqueSuffix + '.' + file.originalname.split('.').pop());
  }
});

const upload = multer({ storage: storage });

6. Serving Uploaded Files

Once a file is uploaded to the /uploads folder, it isn't automatically visible to the world. You need to tell Express to make that folder "Static" so users can view the images via a URL.

// This makes http://localhost:3000/my-image.jpg work
app.use(express.static('uploads'));

7. The Upload Lifecycle

  1. The Client sends a request with enctype="multipart/form-data".

  2. The Route hits the Multer middleware first.

  3. Multer streams the file to the disk and creates req.file.

  4. The Handler (your function) runs, saves the file path to a database, and sends a response.

Summary

Handling files doesn't have to be intimidating. By using Multer, you turn a complex stream of data into a simple object you can manipulate. Just remember:

  • Use enctype="multipart/form-data" in your HTML.

  • Use upload.single() or upload.array() in your routes.

  • Configure diskStorage if you want human-readable filenames.