Multer SetUP

Vikrant SinghVikrant Singh
5 min read

πŸ“„ Complete Multer Documentation


βœ… What is Multer?

Multer is a Node.js middleware for handling multipart/form-data β€” primarily used for file uploads.

  • Built on top of busboy for efficiency.

  • Supports file storage in disk or memory.

  • Adds req.body for text fields & req.file or req.files for uploaded file(s).

πŸ“Œ Note: Multer will only process forms encoded as multipart/form-data.


🧩 How Multer Works

scssCopyEditBrowser (Form) 
    ⇩
Server (Express + Multer Middleware)
    ⇩
Store on Disk or Memory
    ⇩
Save to DB (e.g., MongoDB/GridFS)

βš™οΈ Project Setup

bashCopyEditmkdir my-multer-app
cd my-multer-app
npm init -y
npm install express mongoose multer ejs nodemon sharp

Update "main" to app.js in your package.json.


πŸ—‚οΈ Folder Structure

pgsqlCopyEditmy-multer-app/
β”œβ”€β”€ app.js
β”œβ”€β”€ multer-setup.js
β”œβ”€β”€ models/
β”‚   └── userModel.js
β”œβ”€β”€ views/
β”‚   β”œβ”€β”€ index.ejs
β”‚   └── show.ejs
β”œβ”€β”€ public/
β”‚   └── images/uploads/
β”œβ”€β”€ package.json

πŸ“„ Basic Express Boilerplate

app.js

const express = require("express");
const mongoose = require("mongoose");
const upload = require("./multer-setup");
const sharp = require("sharp");
const User = require("./models/userModel");

const app = express();
app.set("view engine", "ejs");

mongoose.connect("mongodb://127.0.0.1:27017/testingdb");

app.get("/", (req, res) => {
  res.render("index");
});

app.post("/upload", upload.single("image"), async (req, res) => {
  if (!req.file) return res.send("File not found!");

  let newBuffer = req.file.buffer;

  // πŸ“ Resize large files using Sharp
  if (req.file.size > 2 * 1024 * 1024) {
    newBuffer = await sharp(req.file.buffer)
      .resize({ width: 1920 })
      .toBuffer();
  }

  await User.create({
    name: req.body.name || "Default Name",
    image: newBuffer,
  });

  res.send("File uploaded and saved to MongoDB!");
});

app.get("/show", async (req, res) => {
  const files = await User.find();
  res.render("show", { files });
});

app.listen(3000, () => {
  console.log("Server running on http://localhost:3000");
});

βœ… MongoDB Model

models/userModel.js

const mongoose = require("mongoose");

const userSchema = mongoose.Schema({
  name: String,
  image: Buffer,
});

module.exports = mongoose.model("User", userSchema);

βœ… EJS Templates

views/index.ejs

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Upload File</title>
</head>
<body>
  <h1>Upload File</h1>
  <form action="/upload" method="POST" enctype="multipart/form-data">
    <input type="text" name="name" placeholder="Enter name" required />
    <input type="file" name="image" required />
    <button type="submit">Upload</button>
  </form>
</body>
</html>

views/show.ejs

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Show Files</title>
</head>
<body>
  <h1>Uploaded Images</h1>
  <% files.forEach(function(file) { %>
    <img style="width: 100px;" 
         src="data:image/png;base64,<%= file.image.toString('base64') %>" 
         alt="Image" />
  <% }); %>
</body>
</html>

βœ… Multer Setup (Memory Storage + File Filter + Size Limit)

multer-setup.js

const multer = require("multer");
const path = require("path");

// Memory Storage
const storage = multer.memoryStorage();

// File type filter
function fileFilter(req, file, cb) {
  const allowedExt = [".png", ".jpeg", ".jpg", ".webp"];
  const ext = path.extname(file.originalname).toLowerCase();
  const result = allowedExt.includes(ext);

  if (result) {
    cb(null, true);
  } else {
    cb(new Error("These file types are not allowed"), false);
  }
}

// Create the Multer upload instance
const upload = multer({
  storage: storage,
  fileFilter: fileFilter,
  limits: {
    fileSize: 2 * 1024 * 1024, // 2MB limit
  },
});

module.exports = upload;

βœ… Explanation: Memory Storage

  • Memory Storage keeps uploaded files in RAM as a Buffer.

  • Useful when you want to store file data directly in MongoDB.

  • Fast for small files, but be careful with large uploads β€” they consume server RAM.


βœ… File Type Filtering

  • Use fileFilter to allow only specific file extensions.

  • E.g., only accept PNG, JPEG, JPG, or WEBP files.

  • If a file type is not allowed, the middleware rejects it with an error.


βœ… File Size Limits

  • Set limits: { fileSize: X } in Multer.

  • If a file exceeds the limit, Multer automatically rejects the upload.


βœ… Reducing File Size with Sharp

  • If a file is larger than 2MB, you can compress or resize it.

  • Sharp lets you resize images before saving to your DB.

  • Example: resize to width 1920px and convert to Buffer.

const sharp = require("sharp");

if (req.file.size > 2 * 1024 * 1024) {
  newBuffer = await sharp(req.file.buffer)
    .resize({ width: 1920 })
    .toBuffer();
}

βœ… Key Concepts Recap

FeaturePurpose
Memory StorageKeep files in RAM as Buffer β†’ store in MongoDB
Disk StorageStore files on server filesystem
File FilterValidate allowed file types/extensions
LimitsSet maximum file size to prevent large uploads
SharpResize or compress images before saving

⚑ Common Pitfalls

1️⃣ Always match your form’s input name (name="image") with upload.single("image").

2️⃣ Use enctype="multipart/form-data" in forms for file uploads.

3️⃣ When storing as Buffer, use req.file.buffer β€” not req.file.filename.

4️⃣ For displaying images from Buffer, use:

<img src="data:image/png;base64,<%= file.image.toString('base64') %>" />

5️⃣ Always handle errors: e.g., invalid file type or exceeding file size.


βœ… Summary Cheatsheet

jsCopyEdit// Memory storage + filter + limit + sharp resizing
const upload = multer({
  storage: multer.memoryStorage(),
  fileFilter: fileFilter,
  limits: { fileSize: 2 * 1024 * 1024 },
});

// Resize if needed
if (req.file.size > 2MB) {
  buffer = await sharp(req.file.buffer).resize().toBuffer();
}

πŸš€ Ready-to-Go Commands

bashCopyEditnpm start
# Visit: http://localhost:3000
  • Upload an image using your form.

  • View all uploaded images at /show.


πŸŽ‰ Done!

Now you have a complete, clear, production-ready Multer setup for:

  • πŸ“₯ Uploading files to server RAM

  • 🧹 Filtering unwanted file types

  • πŸ“ Limiting file size

  • βœ‚οΈ Reducing file size with Sharp

  • πŸ“¦ Saving to MongoDB

  • πŸ–ΌοΈ Displaying images from Buffer in EJS.

0
Subscribe to my newsletter

Read articles from Vikrant Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Vikrant Singh
Vikrant Singh