Skip to main content

Command Palette

Search for a command to run...

Storing Uploaded Files and Serving Them in Express

Updated
6 min read
Storing Uploaded Files and Serving Them in Express

The first time I uploaded a file in Express and it actually worked…

I felt pretty good.

File reached the server.

Great.

Done.

Or so I thought.

Then the next question hit me.

Okay…

where did the file actually go?

And how do I access it again?

That was the part I hadn’t thought about.

Uploading is only half the story.

Storage and serving matter too.

And honestly…

that was when this topic started making sense.


My First Assumption Was Wrong

I thought:

Upload file.

Server has it.

Done forever.

Very vague thinking 😄

But files have to live somewhere.

Server has to store them.

And if users need access later…

you need a way to serve them.

That was the missing piece.


Where Uploaded Files Are Stored

In simple setups…

uploaded files often go into a folder on your server.

Something like:

uploads/

Very common.

Maybe:

project/
 ├── app.js
 ├── uploads/

And that folder holds uploaded files.

Simple.

That was my first setup.


Upload Storage Folder Structure


This Felt Like A Realization

Files weren’t floating around inside Express.

They were just stored on disk.

As actual files.

That sounds obvious now.

But I genuinely hadn’t thought of it that way early on.


Example Storage Setup

With Multer:

const upload=
multer({

 dest:"uploads/"

});

This says:

Store incoming files in:

uploads/

Very straightforward.

And honestly…

good enough to begin.


Local Storage vs External Storage

This confused me by name.

Simple beginner view:

Local storage here means:

Files stored on your own server or machine.

Like the uploads folder.


External storage means:

Files stored somewhere outside your app server.

Separate storage services.

Different concept.

I didn’t go deep into that initially.

And honestly…

you don’t need to for understanding basics.


I Thought Local Storage Meant Browser Local Storage

Yes…

I made that mistake 😄

I heard “local storage” and thought of browser localStorage.

Different thing entirely.

Worth saying clearly.

I mixed them up once.


Then I Asked…

How do users actually access uploaded files?

If image exists in uploads folder…

how does browser see it?

That led me to static file serving.

And that was another “ohhh” moment.


Serving Static Files In Express

This is the pattern that made sense:

app.use(

"/uploads",

express.static(
"uploads"
)

);

At first I copied this without fully getting it.

Then I realized:

It maps a URL path…

to a folder.

That is the whole idea.

And once I saw that…

it felt simple.


Static File Serving Flow


Accessing Uploaded Files Via URL

Suppose file exists:

uploads/photo.jpg

And you have:

app.use(
"/uploads",
express.static(
"uploads"
)
);

Then file can be accessed at:

http://localhost:3000/uploads/photo.jpg

And honestly…

seeing that work felt satisfying.

Because full cycle now made sense.

Upload.

Store.

Access.

Done.


Static Files Took Me A Moment To Understand

The word “static” confused me.

It just means files served directly.

Like:

Images.

CSS.

Documents.

Files that don’t need route logic every time.

That’s enough to understand the idea.


Folder-Based Thinking Helped

I started picturing:

Request asks:

/uploads/photo.jpg

Express checks mapped folder.

Finds file.

Serves it.

Very simple.

That mental picture helped.


One Thing I Learned About Filenames

Be careful with filenames.

Very quickly I realized:

Two users may upload:

image.jpg

Now what?

Collision problem.

That is why unique names often matter.

I didn’t think about that initially.

Worth noting.


Safe File Handling Matters Too

This topic opened my eyes a bit.

Not every uploaded file should be trusted blindly.

Things I started hearing more:

Check file type.

Check file size.

Limit uploads.

Avoid accepting everything.

And honestly…

that makes sense.

Even at beginner level.


Example File Filter Idea

Conceptually:

Only allow images.

Reject other types.

That kind of thinking matters.

Even if you keep implementation simple at first.


One Mistake I Made

I thought storing files in uploads folder automatically made them public.

Not true.

Storage and serving are separate decisions.

That took me a little time.

Important distinction.


Another Mistake

I thought:

If I use express.static…

everything is safe automatically.

Not exactly.

You still think about what you expose.

That was another lesson.


Tiny Practice Setup

Create:

uploads/

Put:

test.jpg

Add:

app.use(
"/uploads",
express.static(
"uploads"
)
);

Open:

localhost:3000/uploads/test.jpg

That tiny exercise teaches a lot.

Honestly.


Why This Felt Like Completing The Picture

Before this…

I only understood upload step.

Now I understood:

Where file goes.

How file is served.

How users access it.

That made file handling feel complete.

Much more practical.


What Finally Made It Click

I stopped thinking:

Uploading is the whole feature.

And started thinking:

Uploading, storing, and serving are three parts of one flow.

That made everything connect.

That was the real shift.


Quick Recap

  • Uploaded files often go into a folder

  • Local storage means files stored on your server

  • Express can serve files with express.static()

  • Files can be accessed via URL

  • Safe file handling matters

  • Storage and serving are related but different

That’s the foundation.


Conclusion

At first I thought file upload was the hard part.

Turns out…

storing and serving files is just as important.

And honestly…

that is where the feature starts feeling complete.

Upload file.

Store it.

Serve it.

Access it.

That’s the core flow.

If you remember one thing from this article, remember this:

Uploading stores the file…
serving makes the file accessible.

That idea made it click for me.

If you like this simple learning-style explanation,
I write more notes at
devwithsahil.hashnode.dev
and share progress on LinkedIn 🙂