1 · What is Multer?

Multer is Express middleware that parses multipart/form‑data — the encoding used for file uploads. It adds a file / files object to the req object, containing metadata and (optionally) the file buffer or path.

2 · Installation & Basic Setup

// terminal
npm i multer

// app.js
import express from "express";
import multer  from "multer";

const upload = multer({ dest: "uploads/" });
const app = express();

app.post("/profile",
    upload.single("avatar"),   // field name: avatar
    (req, res) => {
        console.log(req.file);   // metadata + file.path
        res.json({ status: "ok" });
    }
);
app.listen(3000);
        

Note: The temporary uploads/ directory must exist or Multer throws ENOENT.

3 · Storage Engines

3.1 · diskStorage()


const storage = multer.diskStorage({
    destination(req, file, cb){
        cb(null, "public/img");
    },
    filename(req, file, cb){
        const unique = Date.now() + "-" + Math.round(Math.random()*1e9);
        cb(null, unique + "-" + file.originalname);
    }
});
const upload = multer({ storage });
        

3.2 · memoryStorage()

Stores files in RAM — ideal for quick transformations (e.g., Sharp image resize) before streaming elsewhere.


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

3.3 · Custom Storage

Implement a class exposing _handleFile() and _removeFile() to stream to S3, GridFS or any destination.

4 · Upload Middleware Patterns

4.1 · Single File

upload.single("avatar")

4.2 · Multiple Files (Same Field)

upload.array("photos", 5);

4.3 · Mixed Fields


upload.fields([
    { name:"avatar", maxCount:1 },
    { name:"gallery", maxCount:8 }
]);
        

4.4 · Accept Any

upload.any();

4.5 · No Files

upload.none(); // only text fields

5 · File Filtering


function imageFilter(req, file, cb){
    const ok = ["image/png", "image/jpeg"].includes(file.mimetype);
    ok ? cb(null, true) : cb(new Error("Only PNG/JPEG allowed"));
}
const upload = multer({ storage, fileFilter: imageFilter });
        

6 · Limits & Security

Common limits:


const upload = multer({
    storage,
    limits:{
        fileSize: 2 * 1024 * 1024,   // 2 MB
        files: 5,
        parts: 20,
    }
});
        

Security checklist:

7 · Error Handling


app.post("/upload", (req, res, next) => {
    upload.single("doc")(req, res, function(err){
        if (err instanceof multer.MulterError){
            // Multer‑specific (LIMIT_FILE_SIZE, LIMIT_PART_COUNT…)
            return res.status(400).json({ error: err.code });
        } else if (err){
            return next(err);        // unknown
        }
        res.send("Uploaded ✓");
    });
});
        

8 · Streaming Workflows

For large files (> 50 MB) or serverless environments, prefer streaming directly to cloud storage to avoid local disk I/O:


// example: multer‑s3
import multerS3 from "multer-s3";
import { S3Client } from "@aws-sdk/client-s3";

const s3 = new S3Client({});
const upload = multer({
    storage: multerS3({
        s3,
        bucket: "my‑bucket",
        key: (req, file, cb) => cb(null, Date.now() + "-" + file.originalname)
    })
});
        

9 · Common Gotchas

10 · API Reference Quick Sheet

MethodSignaturePurpose
single(name) string → middleware Handle exactly one file on a field.
array(name,max) string, int → middleware Handle <= max files under one field.
fields(spec[]) FieldSpec[] → middleware Mixed named fields.
none() → middleware Reject any file upload.
any() → middleware Accept files on any field.