Storing Uploaded Files and Serving Them in Express

File uploads are a very common feature in modern web applications.
Examples include:
Profile pictures
Documents
PDFs
Product images
Videos
When users upload files, the backend must:
Store the file safely
Serve the file when needed
In this article, we’ll understand:
Where uploaded files are stored
Local storage vs external storage
Serving static files in Express
Accessing uploaded files using URLs
Basic security considerations
Let’s start with the basics.
What Happens When a User Uploads a File?
Suppose a user uploads an image.
The flow usually looks like this:
User Uploads File
↓
Server Receives File
↓
File Stored Somewhere
↓
Server Provides URL to Access File
The backend decides:
Where the file should be stored
How the file should be served later
Where Are Uploaded Files Stored?
Uploaded files can be stored in different places.
The two most common approaches are:
Local Storage
External/Cloud Storage
Local Storage
In local storage, files are stored directly inside the server project folder.
Example folder structure:
project/
│
├── uploads/
│ ├── image1.png
│ ├── profile.jpg
│
├── server.js
Here:
Uploaded files go into the
uploadsfolderThe server manages those files directly
Why Local Storage Is Used
Local storage is useful for:
✅ Small projects ✅ Learning projects ✅ Personal applications ✅ Development environments
It is simple to set up and easy for beginners.
External Storage
Large applications usually use external cloud storage services.
Examples include:
AWS S3
Cloudinary
Google Cloud Storage
In this approach:
Server uploads file to cloud storage
instead of storing it locally.
Why External Storage Is Used
External storage helps with:
✅ Scalability ✅ Faster delivery ✅ Better reliability ✅ Reduced server load
This is commonly used in production applications.
Local Storage vs External Storage
| Feature | Local Storage | External Storage |
|---|---|---|
| Setup | Simple | More complex |
| Scalability | Limited | High |
| Best For | Small projects | Large applications |
| File Access | From server folder | From cloud URL |
| Storage Responsibility | Server | Cloud provider |
Upload Folder Structure
A clean folder structure is important.
Example:
project/
│
├── uploads/
│ ├── users/
│ ├── products/
│ ├── documents/
│
├── routes/
├── controllers/
├── server.js
This keeps uploaded files organized.
Serving Static Files in Express
By default, Express does not automatically expose files from folders.
To make files publicly accessible, we use:
express.static()
Basic Example
const express = require("express");
const app = express();
app.use(express.static("uploads"));
app.listen(3000);
This tells Express:
"Serve files from the uploads folder"
How Static File Serving Works
Suppose this file exists:
uploads/profile.jpg
It can now be accessed using:
http://localhost:3000/profile.jpg
Express automatically serves the file.
Static File Serving Flow
User Requests File URL
↓
Express Checks uploads Folder
↓
File Found
↓
File Sent to Browser
Serving Files from a Specific Route
We can also create a custom route.
Example:
app.use("/uploads", express.static("uploads"));
Now files are accessed like this:
http://localhost:3000/uploads/profile.jpg
This approach is cleaner and more common.
Example Upload Flow
User Uploads image.png
↓
File Stored in uploads/
↓
Database stores file path
↓
Frontend uses image URL
This is how many real-world applications manage uploaded files.
Accessing Uploaded Files via URL
Suppose a file is stored as:
uploads/avatar.png
Frontend can access it through:
http://localhost:3000/uploads/avatar.png
This URL can be used inside:
<img>tagsAPI responses
User profile pages
Example Frontend Usage
<img src="http://localhost:3000/uploads/avatar.png" />
The browser requests the image from the Express server.
Security Considerations for File Uploads
File uploads can become dangerous if not handled properly.
Here are some important safety practices.
Validate File Types
Only allow expected file types.
Example:
✅ Images ✅ PDFs
Avoid accepting unknown executable files.
Limit File Size
Large uploads can overload the server.
Always set upload size limits.
Rename Uploaded Files
Avoid using original filenames directly.
Instead of:
myphoto.png
Use unique filenames:
172839_profile.png
This prevents conflicts.
Avoid Public Access to Sensitive Files
Not every uploaded file should be public.
Example:
Private documents
User identity files
Store sensitive files securely.
Never Trust User Input
Users may upload harmful files intentionally.
Always validate:
File type
File size
File extension
on the backend.
Real-World Example
Imagine a social media app.
Flow:
User uploads profile picture
↓
Server stores image
↓
Image URL saved in database
↓
Frontend displays image
This same pattern is used in many applications.
Practice Assignment
Try these tasks yourself.
1. Create an uploads Folder
Inside your Express project:
uploads/
2. Serve Static Files
Use:
express.static()
to expose the uploads folder.
3. Access Files Using URL
Store a sample image and open it in the browser.
Example:
http://localhost:3000/uploads/sample.png
4. Think About Security
Ask yourself:
What file types should be allowed?
What happens if users upload huge files?
Should every uploaded file be public?
These questions are important in real-world backend systems.
Final Thoughts
Handling uploaded files is a core backend development skill.
In Express applications, developers commonly:
Store files locally or in cloud storage
Serve files using static middleware
Access files through URLs
Protect uploads with validation and security rules
Understanding file storage and static file serving helps you build:
Social media apps
E-commerce platforms
Portfolio websites
Document management systems
As your projects grow, you’ll eventually move from local storage to cloud-based solutions.
But learning the local Express workflow first builds a strong foundation.
And now, you know what storing and serving uploaded files in Express is.
If you have any doubt or want to connect, feel free to drop a comment — I’d be happy to help.
Thanks for reading, and see you in the next blog!
Peace ✌️ and Happy Learning!




