The first post in this series covers why I wait two weeks before installing any new release. npm has this built in: min-release-age won't install any version that was published less than 14 days ago. Here is the setup I put in a TypeScript monorepo with a Next.js site and an Expo app.

Two things that may already protect you

Check these first.

Add a cooldown to .npmrc

Put this in an .npmrc at the root of each project and commit it. Build services that run npm in your repo pick it up too (Vercel and EAS both do).

min-release-age=14
ignore-scripts=true

min-release-age (npm 11.10 and later) only installs versions published at least that many days ago. Older npm ignores the line, which is fine, because lockfile installs are exact anyway. ignore-scripts=true covers the older npm on build servers: dependency scripts are skipped, while your own npm run scripts still run (only pre/post hooks are skipped).

I saw the rule work the same day. Installing @axe-core/playwright, npm skipped 4.14.0 (published that day) and installed 4.13.0 on its own.

For an urgent security fix, override it on purpose for that one install and say so in the commit message:

npm install some-package@latest --min-release-age=0

Record the script decisions in package.json

I denied both packages explicitly with npm install-scripts deny, so the decision lives in the repo and not only in one machine's npm version:

{
  "allowScripts": {
    "fsevents": false,
    "unrs-resolver": false
  }
}

Use npm ci on build servers

CI and hosting services generally don't have a package age setting of their own. They build from what you commit, so the rules have to live in committed files. Have every CI job and build server install with npm ci, which installs the exact lockfile and fails if package.json and the lockfile disagree, instead of quietly resolving something newer:

npm ci

Most services let you set the install command. On Vercel, for example, it goes in vercel.json:

{
  "installCommand": "npm ci"
}

Verify signatures

I added npm audit signatures to the full check script in every project. It verified all 1,611 packages.