Serving Static Files
Objectives
By the end of this lesson, you should be able to:
- Serve a folder of static files (CSS, images, HTML) with
express.static - Explain how a request path maps to a file inside the static folder
- Combine static file serving with regular routes in the same app
💡 Why this matters: Not everything a server sends back is generated dynamically, a CSS file, a logo image, a downloadable PDF, are usually the same file every time.
express.statichands these out directly and efficiently, without writing a route for each one.
⚠️ A note on verification: every snippet and every response shown below was actually run and tested with real HTTP requests.
Setting Up a Static Folder
Given a public folder containing style.css and hello.html:
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'public')));
app.listen(4005);
curl http://localhost:4005/style.css
body { color: navy; }
curl http://localhost:4005/hello.html
<h1>Static HTML file</h1>
express.static(folderPath) returns middleware (Module 7 covers what middleware means in depth) that serves every file inside folderPath directly, matched by its path relative to that folder. A file at public/style.css becomes reachable at /style.css, the public part of the path never appears in the URL. path.join(__dirname, 'public') (Module 4’s path module) builds the folder’s absolute path correctly regardless of where the server is started from.
Static Files and Regular Routes Together
app.use(express.static(path.join(__dirname, 'public')));
app.get('/api/status', (req, res) => {
res.json({ status: 'ok' });
});
Static file serving and regular app.get/app.post routes coexist in the same app without conflict, a request first checks whether it matches a file in the static folder, if not, it falls through to the regular routes registered afterward. This combination, static assets plus dynamic routes, is exactly how Module 6 (Server-Rendered Views) serves a page’s CSS alongside its dynamically rendered HTML.
Try It
- Create a
publicfolder with an HTML file and a CSS file, serve it withexpress.static, and fetch both withcurl. - Add an image file to the same folder, and confirm it’s reachable at its path too, without any additional code.
- Add a regular
app.get('/api/health', ...)route to the same app as the static folder, and confirm both the static file and the API route work correctly in the same running server. - Explain, in your own words, why the folder name (
public) doesn’t appear anywhere in the URLs used to reach the files inside it.
Recap
express.static(folderPath)serves every file inside a folder directly, matched to its path relative to that folder.- The folder name itself isn’t part of the resulting URL, only the path inside it.
- Static file serving and regular routes work together in the same app, exactly as needed for a server rendering HTML pages alongside their assets.
Next lesson: sending well-formed JSON responses with the correct HTTP status codes.