# Handling File Uploads in Express with Multer

If you are building a full-stack application, eventually, you are going to need users to upload something. Whether it is a profile picture, a PDF resume, or a gallery of product images, handling file uploads can feel like dark magic the first time you try it.

You might try sending a file to your Express server just like you send regular JSON data, only to find that your server has absolutely no idea what to do with it.

Let's break down exactly why that happens, how the `multipart/form-data` concept works, and how to use a tool called Multer to make file uploads incredibly easy.

## 1\. Why Express Can't Handle Files Out of the Box

Imagine you are sending information to a friend. Sending regular text data (like a username or password in JSON) is like sending a postcard. It is lightweight, the text is right there on the back, and the mail carrier (Express) can read it instantly.

Sending a file (like an image or a video) is entirely different. It is like shipping a heavy, sealed package. You can't just stick a postcard stamp on a package and expect it to arrive. You need a special shipping method.

On the web, this special shipping method is called `multipart/form-data`. When an HTML form sends a file, it chops the data into "multiple parts" so it can be streamed securely over the internet.

By default, Express only knows how to read postcards (JSON or URL-encoded text). If you hand it a heavy package (`multipart/form-data`), it simply ignores it. We need a dedicated "package handler" to open the box, take the file out, and put it somewhere safe.

That is where middleware comes in.

## 2\. Enter Multer: The Package Handler

**Multer** is a middleware specifically designed for Express.js. Its only job is to handle `multipart/form-data`.

When a user submits a file, Multer intercepts the request before it reaches your main route logic. It reads the incoming file stream, saves the file to a folder on your computer, and then attaches a neat little summary of the file to the `req` object so you can use it.

### The Upload Lifecycle

1.  User uploads `profile.jpg` via a form.
    
2.  The request hits your Express server.
    
3.  **Multer intercepts it.** Multer saves the image to a folder (e.g., `/uploads`).
    
4.  Multer creates an object with the file's details (filename, size, path) and attaches it to `req.file`.
    
5.  Your route handler runs, and you can now save the file path to your database.
    

## 3\. Basic Setup & Storage Configuration

Before we upload anything, we need to install Multer:

```bash
npm install multer

```

Next, we need to tell Multer *where* to put the files and *what* to name them. We do this using `multer.diskStorage`.

```javascript
const express = require('express');
const multer = require('multer');
const path = require('path');

const app = express();

// Configure where and how the files are saved
const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        // Tell Multer to save files in the 'uploads' folder
        cb(null, 'uploads/'); 
    },
    filename: (req, file, cb) => {
        // Give the file a unique name (timestamp + original name)
        const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
        cb(null, uniqueSuffix + '-' + file.originalname);
    }
});

// Initialize Multer with our storage engine
const upload = multer({ storage: storage });

```

*(Note: Make sure you actually create a folder named* `uploads` *in your project directory, or Node will throw an error!)*

## 4\. Handling a Single File Upload

Now that Multer is configured, we can inject it into our routes as middleware. If we are expecting a single file (like an avatar), we use `upload.single('fieldName')`.

The string inside `.single()` MUST exactly match the `name` attribute of the input field in your frontend form.

```javascript
// The middleware upload.single('avatar') runs first
app.post('/upload-profile', upload.single('avatar'), (req, res) => {
    
    // If Multer failed, req.file will be undefined
    if (!req.file) {
        return res.status(400).send('No file uploaded.');
    }

    // Multer attached the file info to req.file
    console.log(req.file);
    
    /* 
      req.file looks like this:
      {
        fieldname: 'avatar',
        originalname: 'my-photo.jpg',
        encoding: '7bit',
        mimetype: 'image/jpeg',
        destination: 'uploads/',
        filename: '16987654321-my-photo.jpg',
        path: 'uploads\\16987654321-my-photo.jpg',
        size: 102450
      }
    */

    res.send(`File uploaded successfully! Saved as ${req.file.filename}`);
});

```

## 5\. Handling Multiple File Uploads

What if you are building a product page and need to upload 5 images at once? Instead of `.single()`, we use `upload.array('fieldName', maxCount)`.

```javascript
// Accept an array of files from the 'gallery' input, up to a max of 5 files
app.post('/upload-gallery', upload.array('gallery', 5), (req, res) => {
    
    if (!req.files || req.files.length === 0) {
        return res.status(400).send('No files uploaded.');
    }

    // Notice it is req.files (plural) now! It is an array of objects.
    console.log(req.files);

    res.send(`${req.files.length} files uploaded successfully!`);
});

```

## 6\. Serving the Uploaded Files

Uploading files is only half the battle. If a user uploads a profile picture, they expect to see it on their screen.

By default, Express protects all the folders in your project. If someone tries to visit `http://localhost:3000/uploads/my-photo.jpg`, Express will block them and return a 404 error.

You have to explicitly tell Express to make your `uploads` folder public. We do this using the built-in `express.static` middleware.

```javascript
// Serve the 'uploads' directory publicly
app.use('/uploads', express.static('uploads'));

```

Now, if you have a file named `123-avatar.jpg` inside your uploads folder, your frontend can display it normally using an image tag: `<img src="http://localhost:3000/uploads/123-avatar.jpg" />`

## Summary

Handling files doesn't have to be complicated if you understand the flow:

1.  Files travel as `multipart/form-data`, which Express ignores by default.
    
2.  **Multer** is the middleware that intercepts, reads, and saves these files to your server's disk.
    
3.  Use `upload.single()` for one file, which attaches data to `req.file`.
    
4.  Use `upload.array()` for multiple files, which attaches an array to `req.files`.
    
5.  Expose your upload folder using `express.static` so the frontend can actually display the images.
    

Stay Tune for next Blog! Happy Coding!
