Third-Party Middleware
Beyond the built-ins, the real power of Express is its ecosystem: thousands of npm packages that plug straight into the pipeline as app.use(something()). A handful are so universal that nearly every production app installs them — security headers, CORS, logging, compression, rate limiting, sessions. This page is a tour of those essentials, what each one does, and the order to register them in.
The production starter pack
Package | Purpose |
|---|---|
| Sets security-related HTTP headers |
| Enables cross-origin requests (covered here) |
| HTTP request logging |
| gzip/deflate responses |
| Throttle requests per IP |
| Parse the |
| Server-side sessions |
| Parse |
helmet — security headers
import helmet from 'helmet'
// Sensible secure defaults in one line:
app.use(helmet())
// Or tune individual protections:
app.use(helmet({
contentSecurityPolicy: {
directives: { 'img-src': ["'self'", 'data:', 'https:'] },
},
}))morgan — request logging
import morgan from 'morgan'
// Concise colored output for development:
app.use(morgan('dev'))
// Apache-style combined logs for production:
app.use(morgan('combined'))GET /api/users 200 4.512 ms - 1043 POST /api/users 201 12.880 ms - 87 GET /favicon.ico 404 0.991 ms - 150
compression — smaller responses
import compression from 'compression' // gzip/brotli text responses over a size threshold: app.use(compression())
express-rate-limit — throttling
import rateLimit from 'express-rate-limit'
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15-minute window
max: 100, // 100 requests per IP per window
standardHeaders: true, // send RateLimit-* headers
legacyHeaders: false,
message: { error: 'Too many requests, slow down.' },
})
// Apply globally, or just to sensitive routes:
app.use('/api', limiter)
app.use('/auth/login', rateLimit({ windowMs: 60_000, max: 5 }))Where each one goes — the order
app.js — third-party middleware in order
import express from 'express'
import helmet from 'helmet'
import cors from 'cors'
import compression from 'compression'
import morgan from 'morgan'
import rateLimit from 'express-rate-limit'
import cookieParser from 'cookie-parser'
const app = express()
app.use(helmet()) // 1. security headers
app.use(cors({ origin: 'https://app.example.com' })) // 2. cross-origin policy
app.use(compression()) // 3. compress responses
app.use(morgan('combined')) // 4. log requests
app.use(rateLimit({ windowMs: 60_000, max: 100 })) // 5. throttle
app.use(express.json()) // 6. parse bodies
app.use(cookieParser()) // 7. parse cookies
// 8. your routes
app.use('/api', apiRouter)Vetting a package before you install it
Maintenance — recent commits, open-issue responsiveness, an Express 5-compatible version.
Downloads & dependents — widely-used packages are battle-tested and quickly patched.
Dependency weight — a middleware that pulls in 40 transitive deps enlarges your attack surface.
Does Express already do it? — body parsing and static serving are built in; no package needed.