Node.js8 min read
File Uploads with Multer in Express
Handle file uploads in Node.js with Multer. Upload images, documents, and manage file storage.
Sarah Chen
December 19, 2025
0.0k0
File Uploads with Multer in Express
Multer handles multipart/form-data - the format for file uploads.
Setup
npm install multer
Basic Configuration
const multer = require('multer');
// Simple memory storage
const upload = multer({ dest: 'uploads/' });
// Or disk storage with custom naming
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/');
},
filename: (req, file, cb) => {
const uniqueName = Date.now() + '-' + file.originalname;
cb(null, uniqueName);
}
});
const upload = multer({ storage });
Single File Upload
app.post('/upload', upload.single('avatar'), (req, res) => {
console.log(req.file);
// {
// fieldname: 'avatar',
// originalname: 'photo.jpg',
// filename: '1234567890-photo.jpg',
// path: 'uploads/1234567890-photo.jpg',
// size: 12345
// }
res.json({ file: req.file });
});
Multiple Files
// Multiple files, same field
app.post('/photos', upload.array('photos', 5), (req, res) => {
console.log(req.files); // Array of files
res.json({ files: req.files });
});
// Multiple fields
const cpUpload = upload.fields([
{ name: 'avatar', maxCount: 1 },
{ name: 'gallery', maxCount: 8 }
]);
app.post('/profile', cpUpload, (req, res) => {
console.log(req.files.avatar); // Single file
console.log(req.files.gallery); // Array of files
});
File Filtering
const imageFilter = (req, file, cb) => {
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
if (allowedTypes.includes(file.mimetype)) {
cb(null, true);
} else {
cb(new Error('Only images allowed'), false);
}
};
const upload = multer({
storage,
fileFilter: imageFilter,
limits: {
fileSize: 5 * 1024 * 1024 // 5MB
}
});
Error Handling
app.post('/upload', (req, res) => {
upload.single('file')(req, res, (err) => {
if (err instanceof multer.MulterError) {
if (err.code === 'LIMIT_FILE_SIZE') {
return res.status(400).json({ error: 'File too large' });
}
return res.status(400).json({ error: err.message });
}
if (err) {
return res.status(400).json({ error: err.message });
}
res.json({ file: req.file });
});
});
Memory Storage (for cloud upload)
const upload = multer({ storage: multer.memoryStorage() });
app.post('/upload', upload.single('file'), async (req, res) => {
// req.file.buffer contains file data
// Upload to S3, Cloudinary, etc.
const buffer = req.file.buffer;
// await uploadToCloud(buffer);
res.json({ message: 'Uploaded' });
});
Complete Example
const express = require('express');
const multer = require('multer');
const path = require('path');
const app = express();
const storage = multer.diskStorage({
destination: 'uploads/',
filename: (req, file, cb) => {
const ext = path.extname(file.originalname);
cb(null, `${Date.now()}${ext}`);
}
});
const upload = multer({
storage,
limits: { fileSize: 5 * 1024 * 1024 },
fileFilter: (req, file, cb) => {
const allowed = /jpeg|jpg|png|gif/;
const ext = allowed.test(path.extname(file.originalname).toLowerCase());
const mime = allowed.test(file.mimetype);
if (ext && mime) cb(null, true);
else cb(new Error('Images only!'));
}
});
// Serve uploaded files
app.use('/uploads', express.static('uploads'));
app.post('/api/upload', upload.single('image'), (req, res) => {
if (!req.file) {
return res.status(400).json({ error: 'No file uploaded' });
}
res.json({
url: `/uploads/${req.file.filename}`,
size: req.file.size
});
});
app.listen(3000);
Key Takeaway
Multer handles file uploads in Express. Use single() for one file, array() for multiple. Filter by type/size for security. Use memory storage for cloud uploads, disk storage for local files.
#Node.js#Express#File Upload#Multer#Intermediate