Helmet is a small Express middleware that sets a collection of security-related HTTP headers with sensible defaults, closing off several common attack vectors with a single line of code.
What Does Helmet Actually Do?
Helmet doesn't add new functionality to your app, it sets a curated set of HTTP response headers that instruct browsers to enforce additional security restrictions: preventing your site from being embedded in a hostile iframe, restricting which sources scripts can load from, forcing HTTPS, and more.
Each protection Helmet provides corresponds to a specific, well-documented header, and you can enable, disable, or customize any of them individually if the defaults don't fit your app.
import express from 'express';
import helmet from 'helmet';
const app = express();
app.use(helmet());
app.get('/', (req, res) => res.send('Secured by Helmet'));
helmet() with no options applies a reasonable set of secure defaults, appropriate for most APIs and server-rendered apps out of the box.
Content-Security-Policy restricts which sources scripts, styles, and other resources can load from.
X-Content-Type-Options: nosniff stops browsers from guessing ("sniffing") a response's content type.
X-Frame-Options helps prevent clickjacking by restricting whether your site can be embedded in an iframe.
Strict-Transport-Security (HSTS) tells browsers to always use HTTPS for your domain going forward.
Helmet Headers Cheatsheet
The key headers Helmet manages and what each one protects against.
Header
Protects Against
Content-Security-Policy
XSS and unwanted resource loading
X-Content-Type-Options
MIME-type sniffing attacks
X-Frame-Options
Clickjacking via hidden iframes
Strict-Transport-Security
Downgrade attacks to plain HTTP
Referrer-Policy
Leaking sensitive URL data via the Referer header
Customizing Helmet's Defaults
Default settings sometimes conflict with legitimate app needs, for example, a strict Content-Security-Policy might block a third-party analytics script you actually want to load. Helmet lets you override individual policies rather than disabling protection entirely.
Adjust individual directives rather than disabling contentSecurityPolicy altogether whenever possible, keeping as much protection in place as your app's real requirements allow.
Helmet Is One Layer, Not the Whole Strategy
Helmet closes off a specific, well-known set of header-based vulnerabilities. It doesn't validate input, hash passwords, or replace authentication, it's one layer among several (validation, parameterized queries, rate limiting, HTTPS) that together form a reasonably secure application.
Common Mistakes
Disabling Helmet's contentSecurityPolicy entirely instead of customizing specific directives.
Assuming Helmet alone makes an application "secure" without addressing input validation or authentication.
Not testing the app after adding Helmet, some legitimate third-party scripts/styles can be blocked by the default CSP.
Applying Helmet only to some routes instead of the entire app via app.use().
Key Takeaways
Helmet sets a curated collection of security-related HTTP headers with one line of middleware.
Each header addresses a specific, well-documented browser-level vulnerability.
Helmet's defaults can (and sometimes must) be customized to fit an app's real resource needs.
Helmet is one layer of defense, not a replacement for validation, auth, or safe database queries.
Pro Tip
Add helmet() to every new Express project on day one, before writing any routes. It costs one line, has sensible defaults, and retrofitting a strict Content-Security-Policy onto a large, already-built app is much more work than starting with it in place.
You now know how Helmet secures HTTP headers. Next, learn rate limiting to protect your API from abuse and brute-force attacks.