# Handling File Uploads in Express with Multer

Modern web applications often allow users to upload files such as profile pictures, PDFs, videos, or documents. While handling regular text data in Express is straightforward, file uploads require special handling because browsers send files differently from normal form fields.

This is where Multer becomes useful.

In this blog, you will learn:

*   Why file uploads need middleware
    
*   What Multer is
    
*   How multipart form-data works
    
*   Handling single and multiple file uploads
    
*   Basic storage configuration
    
*   Serving uploaded files in Express
    

* * *

## Why File Uploads Need Middleware

When users submit a normal HTML form, the browser usually sends data in a format called:

```txt
application/x-www-form-urlencoded
```

This works well for text fields like:

*   Username
    
*   Email
    
*   Password
    

But files are binary data. Browsers cannot send images, PDFs, or videos using regular form encoding.

Instead, file uploads use:

```txt
multipart/form-data
```

This format breaks the request into multiple parts:

*   Text fields
    
*   File metadata
    
*   Actual file content
    

The default Express middleware cannot parse multipart form-data.

That is why we need middleware like Multer.

* * *

## What is Multer?

Multer is a middleware for Express that handles:

*   File uploads
    
*   Multipart form-data parsing
    
*   File storage
    
*   Accessing uploaded files inside routes
    

Multer makes file uploads simple by processing incoming files before your route handler executes.

* * *

## Installing Multer

First, create a Node.js project and install Express and Multer.

```bash
npm init -y
npm install express multer
```

* * *

## Creating a Basic Express Server

Create a file named:

```txt
server.js
```

Add the following code:

```javascript
const express = require("express");

const app = express();

app.listen(3000, () => {
    console.log("Server running on port 3000");
});
```

Run the server:

```bash
node server.js
```

* * *

## Understanding multipart/form-data

Suppose a user uploads a profile image.

The browser sends:

*   File name
    
*   File type
    
*   File size
    
*   Binary content
    

Instead of sending everything as plain text, multipart form-data separates each part with boundaries.

Conceptually:

```txt
Request
 ├── Username
 ├── Email
 └── Uploaded Image
```

Multer reads this incoming data and extracts the uploaded files.

* * *

## Handling a Single File Upload

### Step 1: Import Multer

```javascript
const multer = require("multer");
```

* * *

### Step 2: Configure Storage

```javascript
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, "uploads/");
    },

    filename: function (req, file, cb) {
        cb(null, Date.now() + "-" + file.originalname);
    }
});
```

What This Does

*   `destination`
    
    *   Defines where files are stored
        
*   `filename`
    
    *   Creates custom file names
        

Using `Date.now()` helps avoid duplicate file names.

* * *

### Step 3: Create Upload Middleware

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

* * *

### Step 4: Create Upload Route

```javascript
app.post("/upload", upload.single("profile"), (req, res) => {

    console.log(req.file);

    res.send("File uploaded successfully");
});
```

* * *

## Understanding upload.single()

```javascript
upload.single("profile")
```

This means:

*   Accept one file
    
*   Field name must be `"profile"`
    

The HTML form field should match:

```html
<input type="file" name="profile">
```

* * *

## Upload Lifecycle in Express

Here is what happens internally:

```txt
Browser sends file
        ↓
Multer intercepts request
        ↓
File gets stored
        ↓
File info added to req.file
        ↓
Route handler executes
        ↓
Response sent to user
```

This flow is important to understand because Multer processes files before your route logic runs.

![](https://cdn.hashnode.com/uploads/covers/695a275cee3d7756437f49db/280a410d-87f4-4a63-b377-dbf0f6494f27.png align="center")

* * *

## Accessing Uploaded File Information

After upload:

```javascript
req.file
```

contains information like:

```javascript
{
  fieldname: 'profile',
  originalname: 'photo.png',
  encoding: '7bit',
  mimetype: 'image/png',
  destination: 'uploads/',
  filename: '17123456789-photo.png',
  path: 'uploads/17123456789-photo.png',
  size: 34567
}
```

* * *

## Handling Multiple File Uploads

Sometimes users upload:

*   Multiple images
    
*   Documents
    
*   Attachments
    

Multer supports this easily.

* * *

### Using upload.array()

```javascript
app.post("/photos", upload.array("images", 5), (req, res) => {

    console.log(req.files);

    res.send("Multiple files uploaded");
});
```

* * *

## Understanding upload.array()

```javascript
upload.array("images", 5)
```

Means:

*   Accept files from `"images"` field
    
*   Maximum 5 files
    

HTML form:

```html
<input type="file" name="images" multiple>
```

* * *

## Difference Between req.file and req.files

| Upload Type | Property |
| --- | --- |
| Single File | `req.file` |
| Multiple Files | `req.files` |

* * *

## Serving Uploaded Files

Uploaded files are stored on the server.

To make them accessible in the browser:

```javascript
app.use("/uploads", express.static("uploads"));
```

Now uploaded files can be accessed like:

```txt
http://localhost:3000/uploads/file-name.png
```

* * *

## Complete Example

```javascript
const express = require("express");
const multer = require("multer");

const app = express();

const storage = multer.diskStorage({

    destination: function (req, file, cb) {
        cb(null, "uploads/");
    },

    filename: function (req, file, cb) {
        cb(null, Date.now() + "-" + file.originalname);
    }
});

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

app.use("/uploads", express.static("uploads"));

app.post("/upload", upload.single("profile"), (req, res) => {

    res.send("File uploaded successfully");
});

app.listen(3000, () => {
    console.log("Server running on port 3000");
});
```

* * *

## Testing File Uploads

You can test uploads using:

*   HTML forms
    
*   Postman
    
*   Frontend applications
    

Example HTML form:

```html
<form action="/upload" method="POST" enctype="multipart/form-data">

    <input type="file" name="profile">

    <button type="submit">
        Upload
    </button>

</form>
```

* * *

## Why Multer is Popular

Developers use Multer because it:

*   Simplifies file handling
    
*   Works seamlessly with Express
    
*   Supports single and multiple uploads
    
*   Allows custom storage logic
    
*   Makes uploaded files easily accessible
    

Without Multer, handling multipart form-data manually becomes complicated.

![](https://cdn.hashnode.com/uploads/covers/695a275cee3d7756437f49db/5a8b389f-9e76-4da8-a6bb-6d834eb929e2.png align="center")

* * *

## Common Beginner Mistakes

## Forgetting enctype

Wrong:

```html
<form method="POST">
```

Correct:

```html
<form method="POST" enctype="multipart/form-data">
```

Without this, files will not upload correctly.

* * *

### Field Name Mismatch

If:

```javascript
upload.single("profile")
```

Then:

```html
name="profile"
```

must match exactly.

* * *

### Missing Uploads Folder

If the `uploads` folder does not exist, Multer may throw errors.

Always create it before testing.

* * *

## When to Use File Uploads

File uploads are common in:

*   Social media apps
    
*   Resume upload systems
    
*   Blog platforms
    
*   E-commerce product management
    
*   Online learning portals
    
*   Chat applications
    

* * *

## Final Thoughts

Handling file uploads is a fundamental backend skill in Node.js development.

Express alone cannot process multipart form-data efficiently, which is why Multer is commonly used. It acts as a middleware layer that extracts files, stores them, and makes them available inside your routes.

Once you understand:

*   multipart form-data
    
*   upload middleware
    
*   storage configuration
    
*   single vs multiple uploads
    

you can build more advanced systems like:

*   Image processing
    
*   Cloud uploads
    
*   File validation
    
*   Drag-and-drop upload systems
    
*   Video upload platforms
