Setting Up Express Application
1. Installing Express
| Command | Purpose |
|---|---|
npm init -y | Initialize package.json |
npm install express | Install Express 5+ EXPRESS 5 |
npm install -D nodemon | Auto-restart on file changes |
npm install -D @types/express | TypeScript type definitions |
node --version | Requires Node.js 18+ (20 LTS recommended) |
Example: Minimal install & run
mkdir my-api && cd my-api
npm init -y
npm install express
npm pkg set type="module"
node --watch app.js
2. Creating Basic Server
| API | Description |
|---|---|
express() | Factory creating an Express application instance |
app.listen(port, host?, backlog?, cb?) | Bind HTTP server; returns http.Server |
http.createServer(app) | Manual server creation (needed for HTTPS / WebSockets) |
Example: Bootstrap server
import express from "express";
const app = express();
const port = process.env.PORT || 3000;
app.get("/", (req, res) => res.json({ status: "ok" }));
const server = app.listen(port, () =>
console.log(`Listening on http://localhost:${port}`)
);
server.on("error", (err) => console.error("Server error:", err));
3. Configuring Application Settings
| Setting | Default | Purpose |
|---|---|---|
env | process.env.NODE_ENV | Environment mode |
etag | weak | ETag generation: weak, strong, false |
case sensitive routing | false | /Foo ≠ /foo |
strict routing | false | /foo ≠ /foo/ |
x-powered-by | true | Disable to hide framework |
trust proxy | false | Behind reverse proxy / load balancer |
json escape | false | Escape <, >, & in JSON output |
query parser | simple | simple, extended, custom fn, or false |
view cache | prod=true | Cache compiled templates |
4. Setting Port and Host
| Pattern | Notes |
|---|---|
process.env.PORT || 3000 | Honor PaaS-assigned port (Heroku, Render, Cloud Run) |
app.listen(port, "0.0.0.0") | Bind all interfaces (Docker, Kubernetes) |
app.listen(port, "127.0.0.1") | Localhost only (behind reverse proxy) |
app.listen(0) | OS-assigned ephemeral port (testing) |
5. Setting View Engine
| Engine | Install | Setup |
|---|---|---|
| EJS | npm i ejs | app.set("view engine", "ejs") |
| Pug | npm i pug | app.set("view engine", "pug") |
| Handlebars | npm i express-handlebars | app.engine("hbs", engine()) |
6. Configuring Views Directory
Example: Views path
import path from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
app.set("views", path.join(__dirname, "views"));
app.set("views", [path.join(__dirname, "views"), path.join(__dirname, "shared")]);
| API | Purpose |
|---|---|
app.set("views", path) | Single directory or array of directories |
app.engine(ext, fn) | Register custom template engine |
7. Enabling Trust Proxy
| Value | Effect |
|---|---|
true | Trust all proxies (use only in dev) |
"loopback" | Trust 127.0.0.1, ::1 |
"linklocal" | Trust loopback + link-local |
"uniquelocal" | Trust loopback + private + ULA |
1 (number) | Trust nth hop from app |
["10.0.0.1", "10.0.0.2"] | Trust specific IPs/CIDRs |
Warning: Setting
trust proxy: true blindly in production allows IP spoofing via X-Forwarded-For. Use the exact hop count or proxy IP.8. Disabling X-Powered-By Header
Example: Hide framework fingerprint
app.disable("x-powered-by");
// or with helmet
import helmet from "helmet";
app.use(helmet()); // also removes X-Powered-By
| Method | Purpose |
|---|---|
app.disable(name) | Set boolean setting to false |
app.enable(name) | Set boolean setting to true |
app.disabled(name) | Returns true if disabled |
app.enabled(name) | Returns true if enabled |
9. Configuring Static File Directory
| Option | Description |
|---|---|
maxAge | Cache-Control max-age (ms or string) |
etag | Enable ETag generation |
index | Index file (default index.html; false to disable) |
dotfiles | allow, deny, ignore |
fallthrough | Pass to next middleware on 404 |
immutable | Add immutable directive to Cache-Control |
setHeaders | Function to set response headers |
Example: Static assets with caching
app.use(express.static("public", {
maxAge: "1y",
immutable: true,
etag: false,
setHeaders: (res, filePath) => {
if (filePath.endsWith(".html")) res.setHeader("Cache-Control", "no-cache");
}
}));
app.use("/cdn", express.static("assets"));
10. Setting Global Template Variables
| Object | Scope | Use |
|---|---|---|
app.locals | App-wide, persists across requests | Site name, version, helpers |
res.locals | Per-request only | Current user, flash messages |