Storing Uploaded Files and Serving Them in Express

Learning web development in public. Writing simple, real-world explanations about web development concepts. Helping beginners understand why things work, not just how.
Search for a command to run...

Learning web development in public. Writing simple, real-world explanations about web development concepts. Helping beginners understand why things work, not just how.
No comments yet. Be the first to comment.
Every day, millions of users upload photos, videos, stories, and reels to Instagram. From a user's perspective, the process appears simple: select media, apply filters, add a caption, and tap "Post."
Building Offline-First Messaging Apps: How Messages Work Without Internet Modern messaging applications have transformed the way people communicate. Whether it's chatting with friends, collaborating w
In this article we'll explore about the Expo Router and React Navigation and answer which one to use in 2026. If you build mobile apps using React Native, one thing becomes obvious very quickly: Navig

Modern mobile apps are no longer just a collection of screens connected together. Apps like Instagram, WhatsApp, Uber, and Netflix operate at massive scale with millions of users, real time systems, o
In this article we'll be exploring react.js and the things of react.js that makes it popular and stand out among other libraries ( no fight over library vs framework ). We'll go through: What problem

Shkaai
68 posts
Uploading files is one thing.
But what happens after upload is where most beginners get confused:
Where does the file go?
How do we access it later?
How does Express serve it?
Let’s break this down step by step.
When you upload a file using something like multer, the file doesn’t magically stay in memory.
It is stored somewhere — usually on your server.
const storage = multer.diskStorage({
destination:"uploads/",
filename: (req,file,cb) => {
cb(null,Date.now()+"-"+file.originalname);
}
});
destination → folder where files go
filename → how file is named
So if a user uploads image.png, it might become:
uploads/1713950000000-image.png
Files are stored on your server filesystem
You control where and how
This is an important concept.
Files are saved in your project folder:
project/
├── uploads/
│ ├── file1.jpg
│ ├── file2.png
Simple to implement
No extra services needed
Not scalable
Files lost if server restarts or crashes
Not suitable for multiple servers
Files are stored outside your server.
Examples:
Amazon S3
Cloudinary
Google Cloud Storage
Highly scalable
Reliable and persistent
CDN support (faster delivery)
Slightly complex setup
Cost involved
Local = “files live with your server”
External = “files live somewhere else”
Now you have files stored.
But how do users access them?
By default, Express does NOT expose your folders.
You have to explicitly allow it.
import express from "express";
const app = express();
app.use("/uploads",express.static("uploads"));
You are telling Express:
“Anything inside
uploads/can be accessed via/uploadsURL”
Now suppose your file is stored as:
uploads/1713950000000-image.png
With static setup:
app.use("/uploads",express.static("uploads"));
You can access it like:
http://localhost:3000/uploads/1713950000000-image.png
File path → becomes URL
No extra route needed
This is where most people mess up.
Uploading files without validation is risky.
Never trust file extensions.
Use mimetype:
const fileFilter= (req,file,cb) => {
const allowed= ["image/jpeg","image/png"];
if (allowed.includes(file.mimetype)) {
cb(null,true);
}else {
cb(newError("Invalid file type"));
}
};
Prevent huge uploads:
limits: {fileSize:5*1024*1024 }// 5MB
Never allow:
.js
.exe
.sh
These can be dangerous if executed.
Don’t trust original names:
cb(null,Date.now()+"-"+file.originalname);
Prevents:
overwriting files
malicious filenames
Instead of:
public/uploads
Use:
uploads/
And expose only via controlled routes if needed.
Not all files should be public.
For sensitive files:
Don’t use express.static
Create protected routes
Upload → file saved on server or cloud
Storage → local or external
Serving → using express.static
Access → via URL
Security → must not be ignored
Upload = “file comes in”
Storage = “file is saved somewhere”
Static serving = “file becomes accessible via URL”