mrkeyoor.com_
Wed 23 Sept 00:34 UTC
npmWeb Backendupdated 22 Sept 2026

nocache review

nocache 4.0.0 is a zero-option Connect middleware that writes three response headers, then calls `next()`: `Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate`, `Expires: 0`, and `Surrogate-Control: no-store`. Version 4 removed the older `Pragma` header and raised the minimum runtime to Node 16. It can discourage compliant browsers, proxies, and surrogate caches from retaining the current response. It cannot purge an object that an edge already stored, inspect CDN policy, vary rules by user, or decide which routes are safe to cache.

Verdict

nocache 4.0.0 installed as one 1 MB package in 0.6 seconds, added no dependencies or audit findings, and writes one fixed three-header policy in our tested setup. Use it on narrowly scoped private routes; skip it when you need configurable caching, CDN invalidation, or only three local header assignments.

We installed it

Lab card: what happened when we installed nocacheScreenshot of nocache documentation
Install✓ · 0.6s1 package on disk · 1 MB
ImportESM import works · require() works · CommonJS package
Browser0.4 KBgzipped (0.8 KB minified), bundled with esbuild
TypesTypeScript types bundled
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does nocache install cleanly?

Yes. In a fresh container with an empty cache, npm install nocache finished in 0.6s, leaving 1 package and 1 MB on disk. npm audit reported no known vulnerabilities.

How much does nocache add to a browser bundle?

0.4 KB gzipped (0.8 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.

Does nocache work with both ESM and CommonJS?

Yes. Both import 'nocache' and require('nocache') worked in Node 22 in our run. The package is published as CommonJS.

Does nocache include TypeScript types?

Yes, type declarations ship inside the package, so no @types install is needed.

nocache or express-cache-controller: which should you use?

express-cache-controller: Choose it when each Express route needs configurable Cache-Control directives. nocache 4.0.0 installed as one 1 MB package in 0.6 seconds, added no dependencies or audit findings, and writes one fixed three-header policy in our tested setup.

When should you not use nocache?

You intend to mount it above static assets or public GET routes. The fixed no-store policy prevents useful browser and surrogate reuse and increases origin traffic.

API stability5/5Version 4 exposes one zero-argument factory whose returned middleware makes three `setHeader()` calls and then invokes `next()`. There is no option object or secondary API to change underneath consumers. The current major did remove the `Pragma` header and Node 14 or 15 support, and the unreleased changelog raises the future floor to Node 24, but the active 4.0.0 call shape is exceptionally small.
Docs3/5The README shows the correct `nocache()` factory call and prints the exact Cache-Control, Expires, and Surrogate-Control values. That is enough to reproduce the implementation. It does not cover route scope, last-writer-wins middleware order, ETag, old cached objects, CDN overrides, Clear-Site-Data, TypeScript, or the traffic cost of disabling storage, so safe deployment still depends on external HTTP knowledge.
Maintenance4/5GitHub reports an unarchived Helmet repository, 142 stars, 1 open issue or pull request, and a push on August 13, 2026. The published 4.0.0 release dates to June 1, 2023, while the current changelog records an unreleased Node 24 requirement. The long release gap is less concerning for three fixed headers, though consumers should watch that pending runtime break.
Ecosystem4/5The npm endpoint counted 3,749,860 downloads in the latest completed week. The returned function follows the standard Connect middleware signature, so Express routers accept it directly, and package-owned declarations cover TypeScript callers. Its role remains intentionally narrow: no adapters, options, purge providers, ESM entry, or cache-key logic exist, and many teams can replace it with three auditable local lines.

Use it if

  • A specific Express or Connect route returns sensitive data and should always send the package's exact three-header policy.
  • Several authenticated routers need the same fixed response headers without repeating local middleware.
  • You want a dependency-free CommonJS helper with bundled TypeScript declarations.
  • Tests at the application and public edge already confirm that later middleware or CDN rules do not replace the headers.
Skip it if

Setup reality

We installed nocache 4.0.0 in a fresh Node 22 Bookworm sandbox. npm finished in 0.6 seconds and left one package using 1 MB. The package was 24 KB unpacked with no direct or peer dependencies, and npm audit found 0 known vulnerabilities. It is CommonJS with no exports map; both require() and ESM import worked. TypeScript declarations are included.

There are no credentials, config files, or native builds. Call the factory once and mount what it returns: app.use(nocache()). Passing nocache without parentheses gives Express the factory instead of the middleware, so the request may never finish. Version 4 always overwrites the same three headers when it runs. A later handler can overwrite one of them and leave a contradictory mix, which makes middleware order part of the cache policy.

Mount it on the smallest router or route that owns private data. A global mount also covers HTML, JSON, errors, downloads, and static files that pass after it. The middleware does not remove ETag or Last-Modified, send Clear-Site-Data, change an edge cache key, or purge an old object. Test the final public response because a reverse proxy can replace origin headers after Express has finished.

Our browser bundle measured 0.8 KB minified and 0.4 KB gzipped, but browser use makes no sense because the function expects Node request and response objects. Version 4 dropped Pragma and supports Node 16 or newer. The repository's unreleased changelog now says Node 24+ will be required later, so treat the next release as a runtime compatibility check even though the middleware body is tiny.

Patterns

Disable storage for one response protect-one-route

const nocache = require('nocache');

app.get('/account/export', nocache(), async (req, res) => {
  res.json(await buildExport(req.user.id));
});

Route-level mounting keeps unrelated public pages and assets outside this fixed `no-store` policy.

Cover an authenticated router protect-private-router

const express = require('express');
const nocache = require('nocache');

const account = express.Router();
account.use(requireUser);
account.use(nocache());
account.get('/profile', showProfile);
app.use('/account', account);

Because `nocache()` runs after authentication here, an authentication failure produced earlier may not receive these headers. Choose order deliberately.

Apply the policy to all later handlers disable-cache-globally

const nocache = require('nocache');

app.use(nocache());
app.get('/account', showAccount);

A global mount also affects any static, public, and error responses below it. That can waste cache capacity and origin bandwidth.

Add headers conditionally apply-for-signed-in-user

const noCache = require('nocache')();

app.use((req, res, next) => {
  if (req.user) return noCache(req, res, next);
  next();
});

Conditional origin headers do not fix a shared cache whose key ignores authentication. Confirm `Vary` and CDN cache-key rules separately.

Keep headers on downstream errors cover-sensitive-errors

app.get('/reset-password', nocache(), async (req, res, next) => {
  try {
    res.render('reset', await loadState(req.query.token));
  } catch (error) {
    next(error);
  }
});

Headers set before the handler survive unless the error middleware replaces them, which matters when an error page can contain private state.

Test the complete policy assert-header-values

const response = await request(app).get('/account/profile').expect(200);
expect(response.headers['cache-control'])
  .toBe('no-store, no-cache, must-revalidate, proxy-revalidate');
expect(response.headers['surrogate-control']).toBe('no-store');
expect(response.headers.expires).toBe('0');

An application test catches later Express overwrites. Inspect the deployed URL too because a proxy can change headers after the app responds.

Mount the returned function call-middleware-factory

const nocache = require('nocache');

app.use(nocache());
// app.use(nocache); // wrong

The export is a factory. Without parentheses, Express invokes the wrong function and does not receive the middleware that calls `next()`.

Separate private and static routes preserve-static-caching

app.use('/private', nocache(), privateRouter);
app.use('/assets', express.static('public', {
  maxAge: '1y',
  immutable: true,
}));

Path scope preserves long-lived asset caching. Check parent routers for an earlier global `nocache()` call.

Do not overwrite one directive later avoid-header-conflict

app.get('/status', nocache(), (req, res) => {
  res.set('Cache-Control', 'public, max-age=30');
  res.json({ok: true});
});

This code leaves `Surrogate-Control: no-store` beside a public Cache-Control value. Use one policy writer instead of producing conflicting headers.

Mount it in a Connect stack use-connect

const connect = require('connect');
const nocache = require('nocache');

const app = connect();
app.use('/session', nocache());
app.use('/session', (_req, res) => res.end('private'));

The middleware only needs Node request and response methods, so it does not depend on Express-specific response helpers.

Write the exact policy locally replace-with-local-code

function noStore(_req, res, next) {
  res.setHeader('Surrogate-Control', 'no-store');
  res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
  res.setHeader('Expires', '0');
  next();
}

These three assignments reproduce version 4.0.0. A local helper is reasonable when another supply-chain package buys you no reuse.

Request browser cache clearing at logout clear-site-cache

app.post('/session/logout', nocache(), (req, res) => {
  res.setHeader('Clear-Site-Data', '"cache"');
  req.session.destroy(() => res.sendStatus(204));
});

nocache does not send Clear-Site-Data. Browser support varies, and this header neither purges CDN objects nor replaces session invalidation.

Alternatives

PackageRegistryPick it when
express-cache-controllernpmChoose it when each Express route needs configurable Cache-Control directives.
helmetnpmChoose it for a wider set of HTTP security headers, while setting cache policy separately.
freshnpmChoose it to evaluate ETag and Last-Modified freshness instead of disabling storage.
cache-control-parsernpmChoose it to parse and inspect Cache-Control values as structured data.

More web backend guides

urllib3 · requests · ws · anyio · httpx · undici · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.