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.
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.
Where Uploaded Files Are Stored
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.
Common approach
const storage = multer.diskStorage({
destination:"uploads/",
filename: (req,file,cb) => {
cb(null,Date.now()+"-"+file.originalname);
}
});
What this does
destination→ folder where files gofilename→ how file is named
So if a user uploads image.png, it might become:
uploads/1713950000000-image.png
Key point
Files are stored on your server filesystem
You control where and how
Local Storage vs External Storage
This is an important concept.
1. Local Storage (on your server)
Files are saved in your project folder:
project/
├── uploads/
│ ├── file1.jpg
│ ├── file2.png
Pros
Simple to implement
No extra services needed
Cons
Not scalable
Files lost if server restarts or crashes
Not suitable for multiple servers
2. External Storage (Cloud)
Files are stored outside your server.
Examples:
Amazon S3
Cloudinary
Google Cloud Storage
Pros
Highly scalable
Reliable and persistent
CDN support (faster delivery)
Cons
Slightly complex setup
Cost involved
Simple understanding
Local = “files live with your server”
External = “files live somewhere else”
Serving Static Files in Express
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.
Solution: static middleware
import express from "express";
const app = express();
app.use("/uploads",express.static("uploads"));
What this means
You are telling Express:
“Anything inside
uploads/can be accessed via/uploadsURL”
Accessing Uploaded Files via URL
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
Key point
File path → becomes URL
No extra route needed
Security Considerations for Uploads
This is where most people mess up.
Uploading files without validation is risky.
1. File Type Validation
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"));
}
};
2. File Size Limit
Prevent huge uploads:
limits: {fileSize:5*1024*1024 }// 5MB
3. Avoid Executable Files
Never allow:
.js.exe.sh
These can be dangerous if executed.
4. Rename Files
Don’t trust original names:
cb(null,Date.now()+"-"+file.originalname);
Prevents:
overwriting files
malicious filenames
5. Store Outside Root (Advanced)
Instead of:
public/uploads
Use:
uploads/
And expose only via controlled routes if needed.
6. Authentication (Important)
Not all files should be public.
For sensitive files:
Don’t use
express.staticCreate protected routes
Final Understanding
Upload → file saved on server or cloud
Storage → local or external
Serving → using
express.staticAccess → via URL
Security → must not be ignored
Simple Mental Model
Upload = “file comes in”
Storage = “file is saved somewhere”
Static serving = “file becomes accessible via URL”



