Skip to main content
Practice Problems

How to handle file uploads in Express.js with Multer?

File Uploads in Express.js

Express.js doesn't handle file uploads natively. Multer is the most popular middleware for handling multipart/form-data (file uploads).


Setup

bash
npm install multer

Basic File Upload

js
const multer = require('multer'); // Store in memory (for processing/uploading to cloud) const upload = multer({ storage: multer.memoryStorage() }); // Single file upload app.post('/upload/avatar', upload.single('avatar'), (req, res) => { console.log(req.file); // { // fieldname: 'avatar', // originalname: 'photo.jpg', // mimetype: 'image/jpeg', // size: 123456, // buffer: <Buffer ...> // } res.json({ message: 'Uploaded!', file: req.file.originalname }); });

Disk Storage with Custom Naming

js
const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, 'uploads/'); }, filename: (req, file, cb) => { const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9); const ext = path.extname(file.originalname); cb(null, file.fieldname + '-' + uniqueSuffix + ext); } }); const upload = multer({ storage }); app.post('/upload', upload.single('file'), (req, res) => { res.json({ path: req.file.path }); });

Multiple Files

js
// Multiple files with same field name app.post('/upload/photos', upload.array('photos', 10), (req, res) => { console.log(req.files); // Array of file objects res.json({ count: req.files.length }); }); // Multiple fields const cpUpload = upload.fields([ { name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 } ]); app.post('/upload/profile', cpUpload, (req, res) => { console.log(req.files['avatar']); // Array with 1 file console.log(req.files['gallery']); // Array with up to 8 files });

File Validation

js
const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 5 * 1024 * 1024, // 5MB max files: 5 // Max 5 files }, fileFilter: (req, file, cb) => { const allowedTypes = ['image/jpeg', 'image/png', 'image/webp']; if (allowedTypes.includes(file.mimetype)) { cb(null, true); } else { cb(new Error('Only JPEG, PNG, and WebP images are allowed'), false); } } }); // Handle Multer errors app.post('/upload', upload.single('image'), (req, res) => { res.json({ success: true }); }); app.use((err, req, res, next) => { if (err instanceof multer.MulterError) { if (err.code === 'LIMIT_FILE_SIZE') { return res.status(400).json({ error: 'File too large (max 5MB)' }); } return res.status(400).json({ error: err.message }); } next(err); });

Upload to Cloud (S3 Example)

js
const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3'); const upload = multer({ storage: multer.memoryStorage() }); const s3 = new S3Client({ region: 'us-east-1' }); app.post('/upload', upload.single('file'), async (req, res) => { const key = `uploads/${Date.now()}-${req.file.originalname}`; await s3.send(new PutObjectCommand({ Bucket: process.env.S3_BUCKET, Key: key, Body: req.file.buffer, ContentType: req.file.mimetype })); res.json({ url: `https://${process.env.S3_BUCKET}.s3.amazonaws.com/${key}` }); });

Summary

FeatureImplementation
Single fileupload.single('field')
Multiple filesupload.array('field', max)
Multiple fieldsupload.fields([...])
File size limitlimits: { fileSize: ... }
Type validationfileFilter callback
Memory storagemulter.memoryStorage()
Disk storagemulter.diskStorage({...})

Production tip: Always validate file type and size. Store files in cloud storage (S3, GCS, Azure Blob) rather than on disk. Use signed URLs for secure access. Process images asynchronously (resize, compress) using libraries like sharp.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems