Middleware for handling `multipart/form-data`.
Multer is a Node.js middleware specifically designed to handle multipart/form-data, the encoding type used when submitting HTML forms with file inputs. Built on top of the busboy parsing library, it integrates seamlessly with Express.js to process file uploads while extracting text fields from the same form submission. The package populates req.file or req.files with file metadata and buffers/paths, while standard form fields appear in req.body.
The middleware exists because Node.js and Express don't natively parse multipart form data—they only handle URL-encoded and JSON payloads by default. Manual parsing of multipart boundaries and binary data is complex and error-prone, requiring stream handling and RFC-compliant parsing. Multer abstracts this complexity into a simple middleware API with configurable storage engines, validation hooks, and memory management.
With over 10 million weekly downloads, Multer is the de facto standard for file uploads in the Express ecosystem. It's used in everything from avatar upload features in social platforms to document management systems and media processing pipelines. The package maintains an LTS release (1.4.5-lts.1) emphasizing stability, making it suitable for production applications that need reliable file handling without frequent breaking changes.
const express = require('express');
const multer = require('multer');
const path = require('path');
const crypto = require('crypto');
const app = express();
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/');
},
filename: (req, file, cb) => {
const uniqueName = crypto.randomBytes(16).toString('hex') + path.extname(file.originalname);
cb(null, uniqueName);
}
});
const fileFilter = (req, file, cb) => {
const allowedTypes = ['image/jpeg', 'image/png', 'image/webp'];
if (allowedTypes.includes(file.mimetype)) {
cb(null, true);
} else {
cb(new Error('Invalid file type. Only JPEG, PNG and WebP allowed.'));
}
};
const upload = multer({
storage: storage,
fileFilter: fileFilter,
limits: {
fileSize: 5 * 1024 * 1024,
files: 3
}
});
app.post('/upload-avatar', upload.single('avatar'), (req, res) => {
res.json({
success: true,
file: {
filename: req.file.filename,
size: req.file.size,
mimetype: req.file.mimetype
},
metadata: req.body
});
});
app.post('/upload-gallery', upload.array('photos', 10), (req, res) => {
res.json({
success: true,
count: req.files.length,
files: req.files.map(f => ({ name: f.filename, size: f.size }))
});
});
app.use((err, req, res, next) => {
if (err instanceof multer.MulterError) {
return res.status(400).json({ error: `Upload error: ${err.message}` });
}
res.status(500).json({ error: err.message });
});
app.listen(3000);Profile picture uploads: Use disk storage with custom filename generation to handle user avatar uploads, applying file type filtering to accept only images and size limits to prevent abuse.
Document management systems: Process multiple file uploads with .fields() to handle mixed form data like PDFs, spreadsheets, and metadata in a single request, storing files with sanitized names and tracking paths in a database.
CSV/Excel import features: Combine memory storage with .single() to buffer uploaded data files entirely in RAM for immediate parsing and validation without disk I/O overhead.
Image galleries with metadata: Use .array() to accept multiple photos while extracting caption and tag fields from req.body, then integrate with image processing libraries like Sharp for thumbnails.
API file proxying: Leverage Multer with custom storage engines to stream uploaded files directly to cloud storage (S3, GCS) using packages like multer-s3, avoiding local disk writes in containerized environments.
npm install multerpnpm add multerbun add multer