Build a RESTful Image Upload API with Node.js, Express, and Multer

by Didin J. on Jul 01, 2025 Build a RESTful Image Upload API with Node.js, Express, and Multer

Learn how to build a RESTful image upload API using Node.js, Express 5, and Multer with validation, storage configuration, and endpoint integration.

Handling file uploads is a common requirement for web applications. Whether you're building a social media platform, admin dashboard, or CMS, being able to accept images from users is essential.

In this updated tutorial, you'll learn how to build a simple yet robust RESTful API using Node.js, Express 5, and Multer for image upload. We'll cover everything from project setup, storage configuration, image validation, to creating endpoints that accept file uploads via multipart/form-data.

By the end of this guide, you'll have a clean and modular image upload API ready to integrate into your frontend or mobile application.


Create a New Express.js Application and Required Modules

We will start this tutorial by creating or generating a web or REST API application using Express.js. 

mkdir image-upload-api
cd image-upload-api
npm init -y
npm install express multer cors

Also, install nodemon as a dev dependency for easier development:

npm install --save-dev nodemon

Update package.json to include:

"scripts": {
  "start": "node app.js",
  "dev": "nodemon app.js"
}

Now, you are ready to create a REST API service for image upload.

Create the Main App (app.js)

Create a file at the root of the project folder.

touch app.js

Add this code:

// app.js
import express from 'express'
import cors from 'cors'
import uploadRoute from './routes/upload.js'
import path from 'path'
import { fileURLToPath } from 'url'

const app = express()
const PORT = process.env.PORT || 3000

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

app.use(cors())
app.use(express.json())
app.use('/uploads', express.static(path.join(__dirname, 'uploads')))

// Routes
app.use('/api/upload', uploadRoute)

app.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}`)
})


Create Upload Route (routes/upload.js)

Create a route folder and upload.js file:

mkdir routes
touch routes/upload.js

Add this code to that file.

// routes/upload.js
import express from 'express'
import multer from 'multer'
import path from 'path'
import { fileURLToPath } from 'url'
import fs from 'fs'

const router = express.Router()

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

// Ensure uploads folder exists
const uploadDir = path.join(__dirname, '../uploads')
if (!fs.existsSync(uploadDir)) {
  fs.mkdirSync(uploadDir)
}

// Multer Storage
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, uploadDir)
  },
  filename: function (req, file, cb) {
    const ext = path.extname(file.originalname)
    const uniqueName = `${Date.now()}-${Math.round(Math.random() * 1E9)}${ext}`
    cb(null, uniqueName)
  }
})

// File Filter: Accept images only
const fileFilter = (req, file, cb) => {
  const allowedTypes = /jpeg|jpg|png|gif/
  const isValid = allowedTypes.test(file.mimetype)
  if (isValid) {
    cb(null, true)
  } else {
    cb(new Error('Only image files are allowed'), false)
  }
}

const upload = multer({
  storage,
  limits: { fileSize: 2 * 1024 * 1024 }, // 2MB
  fileFilter
})

// POST /api/upload
router.post('/', upload.single('image'), (req, res) => {
  if (!req.file) {
    return res.status(400).json({ message: 'No file uploaded' })
  }

  res.status(200).json({
    message: 'Image uploaded successfully',
    filePath: `/uploads/${req.file.filename}`
  })
})

export default router


Run and Test the Node.js, Express.js, and Multer Image Uploader

To test this Express.js application, just run this command.

nodemon

or

npm start

Next, open the Postman application, then change the method to `POST` and the URL to `http://localhost:3000/api/upload`. Change the body to `form-data,` then fill the key as file and pick an image file. You can see the Postman request below.

Node.js, Express.js and Multer Restful API for Image Uploader - Postman Image Upload

You will see this response for a successful upload.

{
    "fileUrl": "http://192.168.0.7:3000/images/image-1553473134646.png"
}

Now, you can check the uploaded image by entering that address from the API response.


Conclusion

In this tutorial, you’ve learned how to build a modern RESTful image upload API using Node.js, Express 5, and Multer. You’ve covered setting up the project, configuring file storage, filtering and validating uploaded images, and handling uploads via an HTTP POST endpoint.

This API serves as a solid foundation for many real-world use cases — from user profile photo uploads to content management systems or e-commerce product images. You can easily extend this by adding:

  • File type restrictions or virus scanning

  • Cloud storage integration (e.g., AWS S3, Cloudinary)

  • Image resizing and optimization (e.g., using Sharp)

  • Authentication and access control

With the growing demand for image handling in modern apps, mastering this kind of API development is an essential backend skill.

You can get the full source code from our GitHub.

That's just the basics. If you need more deep learning about MEAN Stack, Angular, and Node.js, you can take the following cheap course:

Thanks!