javascript 51 lines · 7 steps

Safe image uploads with Multer in Express

A hardened Express upload route that renames files, caps their size and count, and rejects non-image types.

Explained by highlit
1const express = require('express');
2const multer = require('multer');
3const path = require('path');
4const crypto = require('crypto');
5 
6const router = express.Router();
7 
8const ALLOWED_MIME = new Set(['image/jpeg', 'image/png', 'image/webp']);
9 
10const storage = multer.diskStorage({
11 destination: (req, file, cb) => cb(null, path.join(__dirname, '../uploads')),
12 filename: (req, file, cb) => {
13 const unique = crypto.randomBytes(16).toString('hex');
14 cb(null, `${unique}${path.extname(file.originalname).toLowerCase()}`);
15 },
16});
17 
18const upload = multer({
19 storage,
20 limits: { fileSize: 5 * 1024 * 1024, files: 4 },
21 fileFilter: (req, file, cb) => {
22 if (!ALLOWED_MIME.has(file.mimetype)) {
23 return cb(new multer.MulterError('LIMIT_UNEXPECTED_FILE', file.fieldname));
24 }
25 cb(null, true);
26 },
27});
28 
29router.post('/avatars', upload.array('photos', 4), (req, res) => {
30 if (!req.files || req.files.length === 0) {
31 return res.status(400).json({ error: 'No files uploaded' });
32 }
33 
34 const uploaded = req.files.map((f) => ({
35 filename: f.filename,
36 size: f.size,
37 url: `/uploads/${f.filename}`,
38 }));
39 
40 res.status(201).json({ uploaded });
41});
42 
43router.use((err, req, res, next) => {
44 if (err instanceof multer.MulterError) {
45 const status = err.code === 'LIMIT_FILE_SIZE' ? 413 : 400;
46 return res.status(status).json({ error: err.message, field: err.field });
47 }
48 next(err);
49});
50 
51module.exports = router;
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Generating random filenames avoids collisions and stops user-controlled paths from leaking into disk.
  2. 2Enforce size, count, and MIME limits at the middleware layer so bad requests never reach your handler.
  3. 3A dedicated Multer error middleware turns library failures into clean, typed HTTP responses.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Safe image uploads with Multer in Express — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code