# 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.

```javascript
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.

```javascript
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()`.

```javascript
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**.

```javascript
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.

```javascript
// 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.
