Static Files in Express

Welcome to a deeper look at how to serve static files in your Express application. Sometimes you want to share images, CSS files, or JavaScript files with users directly from your server, without writing any custom routes for each file. Think of it like handing out pamphlets at a booth—if somebody wants a particular pamphlet (file), you just hand it over, no questions asked.

By the end of this reading, you’ll understand:

Using express.static

Express gives you a simple, built-in middleware function, express.static(root, [options]), that makes it easy to serve static assets, like images or style sheets. Instead of writing custom endpoints for each file (which can be tedious), you can point Express at a folder, and any file within that folder can be served automatically under a specified URL prefix.

In plainer terms, express.static is a clerk at a library who knows where all the books (files) are, and can hand them out (serve them) whenever someone requests them. If the request matches the section (prefix) and book name (file path) in its library, the file is returned. Otherwise, the clerk simply says, “That book doesn’t exist” (a 404 response).

Connecting the Middleware

To use express.static, you first need to specify:

Then, you connect them to your Express app with app.use(). For example:

app.use('/static', express.static('public'));

This tells Express, “Whenever someone asks for files starting with /static, look in the public folder for that file.” Notice here that public is a relative path—meaning there’s a directory named public in your project root. Express will serve anything in that directory automatically under /static.

Step-by-Step Example / Follow-Along Exercise

Suppose you have a project folder like this:

my-express-app
├── public
│    ├── css
│    │    └── your-style.css
│    ├── images
│    │    ├── doggo.jpg
│    │    └── logo.png
│    ├── scripts
│    │    └── hello.js
│    ├── helloworld.html
│    └── prospectus.pdf
├── app.js
└── package.json

In app.js, you add:

const express = require('express');
const app = express();

app.use('/static', express.static('public'));

app.listen(3000, () => {
  console.log('Server listening on port 3000');
});

Now, how does that /static prefix map to files? Think of it like an address system:

Notice that the “public” folder itself doesn’t appear in the URL. It’s replaced by the /static prefix. This keeps your internal folder structure separate from the URLs you present publicly. It also gives you flexibility: you could rename “public” to something else without changing your public endpoints, or switch from “/static” to another URL prefix if you want.

When and Why to Use Static Serving

Serving static files is perfect for scenarios like:

If your application is more complex and uses a front-end framework or bundler (like React, Angular, or Vue), you might serve your compiled assets via express.static once they’re built.

Real World Example

Imagine you’re creating a small personal portfolio site. Your index page is dynamic, generated by Express, but your resume PDF is static, as are some images of your projects. With app.use('/assets', express.static('public')), you can keep the dynamic pages in your normal routes, and let /assets/ handle resume.pdf, project1.png, etc., seamlessly. Users can download your resume by visiting /assets/resume.pdf.

Further Topics to Explore

What You've Learned

You now know that express.static is the simplest way to serve files right from your Express server. Remember these key takeaways:

This is immensely powerful for quickly sharing front-end assets or public files without reinventing the wheel. As you continue building more robust applications, you’ll often rely on express.static to handle styles, images, scripts, and more.