Stop 05 · Express.js & Web FrameworksTopics · 9/14

File Uploads

Part of the Backend Developer Roadmap

In short

Profile photos, resumes, invoices: users upload files all the time. Files don't arrive as JSON, so Express needs a little help to receive and check them safely.

Handling `multipart/form-data` requests to accept file uploads from clients — typically via middleware like Multer that parses files into memory or disk.

The mascot places a cardboard parcel on a weighing scale at a courier counter.

Think of it like this

The courier counter

At the courier office, the clerk weighs your parcel, checks it's not something banned, and only then accepts it with a receipt. A file upload handler does the same: check the size, check the type, store it, and send back a receipt.

Watch it happen

Uploading a profile photo

multipart
Size check
Type check
Store
201 + URL

1/5The browser sends multipart/form-data with a field called avatar holding the image bytes.

The big ideas

What you need to know

multipart/form-data

Files travel in a special body format. express.json() can't read it, so you use a parser like Multer.

Always set a size limit

Without one, someone can upload a 5 GB file and fill your disk or memory.

Check the type

Allow only the types you need. The filename extension is easy to fake, so treat it as a hint only.

Rename on save

Generate a random file name. User-supplied names can contain ../ tricks or overwrite other files.

See it in code

Walk through the code

js
1import multer from "multer";2 3const upload = multer({4  dest: "uploads/",                       // saved with random names5  limits: { fileSize: 2 * 1024 * 1024 },  // 2 MB6  fileFilter: (req, file, cb) => {7    const ok = ["image/jpeg", "image/png"].includes(file.mimetype);8    cb(null, ok);9  },10});11 12app.post("/me/avatar", upload.single("avatar"), (req, res) => {13  if (!req.file) return res.status(400).json({ error: "Send a JPEG or PNG as 'avatar'" });14  res.status(201).json({ id: req.file.filename, size: req.file.size });15});

1/4dest saves files to disk with random names Multer generates.

An oversized file makes Multer raise an error with code LIMIT_FILE_SIZE. Catch it in your error handler and send a 413.

Save yourself the pain

Common mistakes

Oops

Saving files with file.originalname straight from the user.

Do this instead

Use a random name and keep the original only as data in your database.

Oops

Storing uploads on the server's own disk when it runs on several machines.

Do this instead

Disk storage is fine for learning. In production, store files in object storage like S3 so every server can reach them.

Your mission

Avatar upload

~25 min

Quick check

Why can't express.json() read a file upload from an HTML form?

Go deeper

  1. 1Build an endpoint that accepts a single file upload using Multer.
  2. 2Add file type and size validation before accepting an upload.
  3. 3Learn the trade-off between storing uploads on disk vs streaming directly to cloud storage (S3).

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge