Static Files
Part of the Backend Developer Roadmap
In short
Images, a favicon, a built frontend, a PDF brochure: some files never change per request. Express can hand them out directly, with no route code at all.
Serving files (images, CSS, client bundles) directly from a folder on your server using Express's built-in `express.static` middleware.

Think of it like this
The open library rack
Some college libraries have open racks: walk in, pick the book you need, and go. No librarian has to fetch it for you. express.static is that open rack. Ask for /logo.png and Express picks it straight off the shelf.
Watch it happen
Serving and caching a static file
GET /img/logo.png
1/6The browser asks for the logo. express.static checks public/img/logo.png.
The big ideas
What you need to know
One folder, public URLs
app.use(express.static("public")) makes public/css/app.css available at /css/app.css.
Add a URL prefix
app.use("/static", express.static("public")) serves the same files under /static/... instead.
Cache wisely
maxAge tells browsers how long to keep files. Long caching works best with hashed names like app.3f9a.js.
Only public things
Everything in that folder is downloadable by anyone. Never put .env, uploads or source code there.
See it in code
Walk through the code
1import path from "node:path";2import express from "express";3 4const app = express();5const publicDir = path.join(import.meta.dirname, "public");6 7app.use(express.static(publicDir, { maxAge: "7d" }));8 9app.get("/api/health", (req, res) => res.json({ ok: true }));10 11app.listen(3000);12// public/index.html -> http://localhost:3000/13// public/img/logo.png -> http://localhost:3000/img/logo.png1/4Build an absolute path to the public folder next to this file.
import.meta.dirname gives the folder of the current file in recent Node versions. It means the path works no matter where you start the server from.
Save yourself the pain
Common mistakes
Oops
Using express.static("public") with a relative path and getting 404s when started from another folder.
Do this instead
Build an absolute path from the file's own directory, so it works from anywhere.
Oops
Serving the project root as static, so /package.json and /.env can be downloaded.
Do this instead
Serve only a dedicated public folder that contains nothing private.
Your mission
Serve a tiny site
Quick check
With app.use(express.static("public")), which URL serves public/docs/menu.pdf?
Go deeper
- 1Serve a folder of static assets and confirm they're reachable via URL.
- 2Learn when serving static files from your API server makes sense vs using a CDN.
- 3Configure caching headers for static assets to improve repeat-visit performance.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.