Skip to content

ExpressJS - Static Files

Static files are assets that are sent directly to the client without any server-side processing. This includes files like HTML, CSS, client-side JavaScript, images, fonts, and more. Express provides a powerful built-in middleware, express.static, to handle this task efficiently.

To serve files from a directory, you simply need to pass the name of that directory to the express.static middleware. A common convention is to name this directory public.

my-app/
├── public/
│ ├── css/
│ │ └── style.css
│ ├── images/
│ │ └── logo.png
│ └── js/
│ └── app.js
├── index.js
└── package.json
import express from 'express';
import path from 'path';
import { fileURLToPath } from 'url';
// ES Modules do not have __dirname, so we create it
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const app = express();
const PORT = 3000;
// Serve static files from the 'public' directory
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', (req, res) => {
// This route is not strictly necessary if you have an index.html
// in your public folder, as express.static will serve it by default.
res.send('<h1>Welcome to the Main Page!</h1><p>Static assets are served from the /public folder.</p>');
});
app.listen(PORT, () => {
console.log(`Server is running at http://localhost:${PORT}`);
});

Now, any file in the public directory is accessible from the root of your domain. Express maps the URLs directly to the files:

  • http://localhost:3000/css/style.css will serve the public/css/style.css file.
  • http://localhost:3000/images/logo.png will serve the public/images/logo.png file.
  • Note: The directory name public is not part of the URL.

You can use the express.static middleware multiple times to serve files from several directories. Express will look for a file in the directories in the order they are mounted.

// Serve from a 'public' directory
app.use(express.static('public'));
// Also serve from an 'assets' directory
app.use(express.static('assets'));
// If a request for /logo.png is made, Express will first look
// in the 'public' folder. If not found, it will then look in the 'assets' folder.

For better organization or to avoid naming conflicts, you can create a virtual path prefix. This means the files will only be accessible under that specific URL prefix, even though the files are in a root-level directory.

// This will mount the 'public' directory under the '/static' path prefix.
app.use('/static', express.static('public'));

With this configuration, you would now access your static files using the /static prefix in the URL:

  • http://localhost:3000/static/css/style.css
  • http://localhost:3000/static/images/logo.png
  • Use path.join(): Always use path.join(__dirname, 'public') to create an absolute path to your static assets directory. This prevents issues that can arise from running your application from different locations in your file system.
  • Middleware Order: Place express.static high in your middleware stack, before any route handlers that might intercept requests for static assets. This ensures that requests for assets are handled quickly without unnecessary processing.
  • Production Environment: While express.static is excellent for development and many production scenarios, for high-traffic websites, it is a best practice to offload static asset serving to a dedicated reverse proxy (like Nginx) or a Content Delivery Network (CDN). This frees up your Node.js server to focus on handling dynamic API requests, significantly improving performance and scalability.