CodingNic

Express.js Fundamentals

Serving Static Files

Express.js Fundamentals 8 min read

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.static hands 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:

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

app.use(express.static(path.join(__dirname, 'public')));

app.listen(4005);
bash
curl http://localhost:4005/style.css
text
body { color: navy; }
bash
curl http://localhost:4005/hello.html
text
<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

javascript
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

  1. Create a public folder with an HTML file and a CSS file, serve it with express.static, and fetch both with curl.
  2. Add an image file to the same folder, and confirm it’s reachable at its path too, without any additional code.
  3. 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.
  4. 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.