File Sharing Platform with Node.js and Express.js

Last Updated : 23 Jul, 2025

In today's digital age, the need for efficient File sharing platforms has become increasingly prevalent. Whether it's sharing documents for collaboration or distributing media files, having a reliable solution can greatly enhance productivity and convenience. In this article, we'll explore how to create a file-sharing platform using Node.js and Express.js, two powerful technologies for building web applications.

Output Preview:

File sharing platform using node - preview
Preview of Final Application

Prerequisites:

Approach

  • Initialize an Express.js server to handle HTTP requests and responses.
  • Use Multer middleware to handle file uploads and store uploaded files in a designated directory.
  • Define a Mongoose schema for storing file metadata including path, original name, password (if protected), and download count.
  • Create routes for uploading files, encrypting passwords using bcrypt, and handling password-protected file downloads.
  • Set up EJS templates to render HTML views for file upload form, password prompt, and success/error messages.
  • Implement security measures such as validating input data, handling errors gracefully, and protecting sensitive information.

Steps to Create the Project

Step 1: Type the following command in the terminal to initialize the nodejs project.

npm init -y

Step 2: Install the necessary packages:

npm i bcrypt nodemon express multer dotenv ejs mongoose

Step 3: Define the start scripts in package.json file:

"scripts": {
"start": "nodemon server.js"
},

Step 4: Create a .env file and add the mongo db connection URI as well as define your PORT. I have kept it 3000.

MONGO = your mongodb URI
PORT = 3000

Project Structure:

Screenshot-2024-04-07-001246
Folder structure

The updated dependencies in package.json file will look like:

"dependencies": {
"bcrypt": "^5.1.1",
"dotenv": "^16.4.5",
"ejs": "^3.1.9",
"express": "^4.19.2",
"mongoose": "^8.3.1",
"multer": "^1.4.5-lts.1",
"nodemon": "^3.1.0",
"pug": "^3.0.2"
}

Example: Implementation to show the code for file sharing platform

HTML
<!-- index.ejs -->

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" 
          content="IE=edge">
    <meta name="viewport" 
          content="width=device-width, initial-scale=1.0">
    <title>File Share</title>
</head>

<body>
    <h1 style="text-align: center; 
               margin-bottom: 50px;">
        File Sharing Application
    </h1>
    <% if(locals.fileLink !=null) { %>
        <div style="margin-bottom: 1rem;">
            Your file is uploaded
            <a href="<%= locals.fileLink %>">
                <%= locals.fileLink %>
            </a>
        </div>
        <% } %>
            <form action="/upload" method="post"
                  style="display: grid; gap: 0.5rem; 
                         grid-template-columns: auto 1fr; 
                         max-width: 500px; margin: 0 auto;"
                  enctype="multipart/form-data">
                <label for="file">File:</label>
                <input type="file" name="file" id="file" required>
                <label for="password">Password:</label>
                <input type="password" name="password" 
                       id="password" required>
                <button style="grid-column: span 2;" type="submit">
                  Share
                  </button>
            </form>
</body>

</html>
HTML
<!-- password.ejs -->

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" 
          content="width=device-width, initial-scale=1.0">
    <title>File Share</title>
</head>

<body>
    <h1 style="text-align: center; 
               margin-bottom: 50px;">
        Enter Password
    </h1>

    <% if(locals.error) { %>
        <div style="color: red; margin-bottom: 1rem;">
            Incorrect password
        </div>
        <% } %>

            <form method="post" 
                  style="display: grid; gap: 0.5rem; 
                          grid-template-columns: auto 1fr; 
                         max-width: 500px; margin: 0 auto;">
                <label for="password">Password:</label>
                <input type="password" name="password" 
                       id="password" required>
                <button style="grid-column: span 2;" 
                        type="submit">
                    Download
                </button>
            </form>
</body>

</html>
JavaScript
// server.js

const express = require("express")
const multer = require("multer")
const app = express()
app.use(express.urlencoded({ extended: true }));
const mongoose = require("mongoose")
require("dotenv").config()
const upload = multer({ dest: "uploads" })
const bcrypt = require("bcrypt")
const File = require("./models/File.js")

mongoose.connect(process.env.MONGO)

app.set("view engine", "ejs")

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

app.post("/upload",
    upload.single("file"), async (req, res) => {
        const fileData = {
            path: req.file.path,
            originalName: req.file.originalname
        }
        if (req.body.password != null &&
            req.body.password !== "") {
            fileData.password =
                await bcrypt.hash(req.body.password, 10)
        }

        const file = await File.create(fileData)
        res.render("index",
            { fileLink: `${req.headers.origin}/file/${file.id}` })
    })


app.get("/file/:id", handleDownload)
app.post("/file/:id", handleDownload)

async function handleDownload(req, res) {
    const file = await File.findById(req.params.id)

    if (file.password != null) {
        if (req.body.password == null) {
            res.render("password")
            return
        }

        if (!(await bcrypt.compare(
            req.body.password, file.password))) {
            res.render("password", { error: true })
            return
        }
    }

    file.downloadCount++
    await file.save()
    res.download(file.path, file.originalName)
}
app.listen(process.env.PORT)
JavaScript
// File.js

const mongoose = require("mongoose")

const File = new mongoose.Schema({
    path: {
        type: String,
        required: true
    },
    originalName: {
        type: String,
        required: true
    },
    password: String,
    downloadCount: {
        type: Number,
        required: true,
        default: 0
    }
})

module.exports = mongoose.model("File", File)

Step to Run Application: Run the application using the following command from the root directory of the project

node server.js

Output: Your project will be shown in the URL http://localhost:3000/

File sharing platform using node
Final preview of Platform


Comment

Explore