Dev.to Security πŸ” Cybersecurity πŸ‘ 0 πŸ“– 20 min read

npm minimum release age: a cooldown for dependencies

Setting an npm minimum release age is, for me, the cheapest security measure you can add to a JavaScript project this week. One line in your .npmrc, and npm only installs package versions that are already a few days old.

npm minimum release age: a cooldown for dependencies

Setting an npm minimum release age is, for me, the cheapest security measure you can add to a JavaScript project this week. One line in your .npmrc, and npm only installs package versions that are already a few days old. That sounds trivial, but it targets exactly the moment when supply chain attacks hit.

We have seen the pattern plenty of times since 2025: someone takes over a maintainer account, publishes a version with malware, and it stays available for a few hours up to a few days until scanners or the community report it and the registry removes it. Anyone who runs npm install during that window gets it. That might be your laptop, your CI pipeline or an AI agent that β€œquickly” adds a dependency. A cooldown changes only one thing: you are no longer among the first. On top of that, GitHub put a package firewall with exactly this kind of waiting period into preview on October 20. High time to set this up properly.

In short

A cooldown only lets new package versions into your project after a waiting period: in npm via min-release-age, in pnpm, Yarn and Bun via their own settings with different units, and in Dependabot and Renovate at the level of update PRs. The key finding from my test: npm ci and an npm install with an existing lockfile do not check the age, so a lockfile check belongs in CI. The biggest pitfall is urgent security fixes, for which you need a deliberate exception path.

What you will learn in this article

  • How npm min-release-age works and how to set it up in five minutes
  • Which settings pnpm, Yarn and Bun offer and why the units are tricky
  • Why npm ci bypasses the cooldown and how a lockfile check catches it
  • How to configure Dependabot and Renovate to match the waiting period
  • How to ship an urgent security fix right away anyway

What does the npm minimum release age do?

Before npm installs anything, it builds a dependency tree: for every range such as "zod": "^4.1.0" it looks for the newest matching version. With min-release-age=3 in the configuration, only versions published more than three days ago qualify. If there is a matching older version, npm simply takes that one. If there is none, the command fails with an error. The option was introduced in npm 11.10.0 in February 2026.

There is also the older option before. It takes a fixed date instead of a number of days. If both are set in the same configuration source, before wins according to the npm docs. Across sources the usual order applies: command line before environment variable before project .npmrc before user and global configuration. That matters later for the exception path.

One more term, because it comes up constantly: the lockfile (for npm, the package-lock.json) records which version of each package was actually installed, including all indirect dependencies. If you commit it, every machine gets the same tree.

🎬 Cooldown: a waiting period for new package versions – this animated diagram only runs on my site: watch it on sascha-ms.de

Three layers for a cooldown

You can add the waiting period in three places, and each one protects something different. So it is worth a quick look at the big picture before you touch any configuration files.

Diagram: npm minimum release age in four stages – registry proxy, update bot, package manager and CI lockfile check

Four places where package versions that are too new get stopped

  • Package manager (npm, pnpm, Yarn, Bun): applies whenever versions are resolved again, i.e. with npm install package, npm update or a fresh lockfile.
  • Update bot (Dependabot, Renovate): applies before a pull request with a new version even exists.
  • Registry proxy (GitHub package firewall or your own proxy): applies centrally to every machine that installs through it, including CI runners and agents whose configuration you do not control.

For most teams the first two layers plus a check in CI are enough. The third one is mainly interesting for larger organizations, more on that below.

How to set up npm min-release-age

Prerequisites

  • npm 11.10.0 or newer for min-release-age, npm 12 for the exclusion list min-release-age-exclude. Check with npm -v, update with npm install -g npm@12.
  • A project with a committed package-lock.json.
  • For the lockfile check further down: Node.js 22.18 or newer (TypeScript files run there without a build step).

Step 1: Create the .npmrc in your project

Create an .npmrc in the project folder or extend the existing one. The exclusion for your own scope is optional but sensible: you do not want to block internal packages that your team publishes itself for three days.

# .npmrc
min-release-age=3
min-release-age-exclude[]=@bookshop/*

Commit the file. That way the rule applies to everyone on the team and in CI, not just on your machine. If you also want the protection for all your own projects, put the same line into your user configuration (npm config set min-release-age 3).

Step 2: Test whether the waiting period applies

The easiest test uses a package that publishes new versions every day. TypeScript ships a nightly build under the next tag. Explicitly request a version from today:

npm install [email protected]

In my test with npm 12.2.1, I got exactly what you want to see:

npm error code ETARGET
npm error notarget No matching version found for [email protected] with a date before 10/25/2026, 9:38:42 AM.

If you only ask for typescript@next, on the other hand, npm silently resolves to an older version. In my case the stable 7.0.2 ended up in the project instead of today’s nightly build. That is convenient, but it can surprise you when you deliberately want to test a prerelease.

Step 3: Define an exception path for hotfixes

Sooner or later a security fix appears that you do not want to leave lying around for three days. Because the command line overrides the project configuration, this is enough for a single, consciously reviewed case:

npm install ky@latest --min-release-age=0

Watch out for npm audit fix: if the cooldown blocks the patched release, npm keeps the vulnerable version according to the docs, prints a warning and exits with an error code. A pipeline that runs npm audit fix automatically will fail in that case. That is intended, but your team should know what to do in that moment.

pnpm, Yarn and Bun compared

The other package managers partly had the idea earlier and name it differently. The units are the real danger: the same number 3 means three days in npm, three minutes in pnpm and three seconds in Bun.

Package manager Setting Unit Exclusions
npm min-release-age in .npmrc days min-release-age-exclude (npm 12 and later)
pnpm minimumReleaseAge in pnpm-workspace.yaml minutes (default 1440 per current docs) minimumReleaseAgeExclude
Yarn (Berry) npmMinimalAgeGate in .yarnrc.yml duration, e.g. 1w npmPreapprovedPackages
Bun install.minimumReleaseAge in bunfig.toml seconds minimumReleaseAgeExcludes
# pnpm-workspace.yaml
minimumReleaseAge: 4320 # 3 days in minutes
minimumReleaseAgeExclude:
  - '@bookshop/*'
# bunfig.toml
[install]
minimumReleaseAge = 259200 # 3 days in seconds
minimumReleaseAgeExcludes = ["@bookshop/prices"]

With pnpm, two neighboring settings are worth a look as well: minimumReleaseAgeStrict is enabled automatically as soon as you set minimumReleaseAge yourself, and it makes the installation fail when no version is old enough. minimumReleaseAgeIgnoreMissingTime, however, defaults to true. If a private registry does not return a publish date, the package is waved through without a check.

The gap: npm ci does not check the age

Now comes the part that kept me busy the most while trying this out. I created a lockfile without a cooldown that contained today’s TypeScript nightly. After that I set min-release-age=3 and reinstalled:

rm -rf node_modules
npm ci
npm install

Both commands ran without errors, and the folder still contained the version from that same morning. This is not a bug. The lockfile is a decision that has already been made, and the cooldown only applies when npm resolves versions again. As a result, a lockfile with very new versions can reach your repository in several ways:

  • Someone still works with npm 10 or an early npm 11 version. Those do not know the option and ignore it. In my test, npm 10.9 installed the nightly without any comment.
  • A bot or AI agent updates the lockfile with its own configuration.
  • Someone bypasses the rule locally with --min-release-age=0 and forgets to mention it in the review.

The consequence: the waiting period belongs not only in the .npmrc but also in CI as a check. Specifically, for the versions a pull request newly adds to the lockfile.

A lockfile check in CI with TypeScript

The idea is simple: the script compares the pull request’s lockfile with the one from the target branch, collects all new or changed package versions and asks the registry for their publish dates. The npm registry provides them in the time field of the package metadata (the so-called packument). If a version is newer than allowed or the date is missing, the check fails. The script has no runtime dependencies and runs directly as TypeScript on Node.js 22.18 or newer.

Step 1: Create the project

Create a folder tools/release-age-guard in the repository. You only need TypeScript for type checking; at runtime Node strips the types itself. That is why the tsconfig.json contains erasableSyntaxOnly: it makes the compiler report syntax that Node cannot simply drop, such as enum.

{
  "name": "release-age-guard",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "engines": { "node": ">=22.18" },
  "scripts": {
    "check": "node src/cli.ts",
    "typecheck": "tsc --noEmit",
    "test": "node --test"
  },
  "devDependencies": {
    "@types/node": "^22.18.0",
    "typescript": "^7.0.2"
  }
}
{
  "compilerOptions": {
    "target": "es2023",
    "module": "nodenext",
    "moduleResolution": "nodenext",
    "strict": true,
    "noEmit": true,
    "allowImportingTsExtensions": true,
    "erasableSyntaxOnly": true,
    "verbatimModuleSyntax": true,
    "types": ["node"]
  },
  "include": ["src", "test"]
}

Step 2: Read and compare the lockfile

In a package-lock.json (version 2 or 3), the packages section lists every installed path, for example node_modules/a/node_modules/zod. The package name is everything after the last node_modules/. The function skips workspace folders, links and local paths because they do not come from the registry.

// src/lockfile.ts
export interface LockedPackage {
  name: string;
  version: string;
}

interface LockfileV3 {
  lockfileVersion?: number;
  packages?: Record<string, { version?: string; link?: boolean; resolved?: string }>;
}

// Reads all installed packages from a package-lock.json (lockfileVersion 2 or 3).
export function readLockedPackages(json: string): LockedPackage[] {
  const lock = JSON.parse(json) as LockfileV3;
  if (!lock.packages) {
    throw new Error('package-lock.json without "packages" – please use lockfileVersion 2 or 3');
  }
  const result = new Map<string, LockedPackage>();
  for (const [path, entry] of Object.entries(lock.packages)) {
    // Installed packages only; skip workspace folders and links
    if (!path.includes('node_modules/') || entry.link || !entry.version) continue;
    // Local paths and git dependencies have no registry tarball
    if (entry.resolved && !entry.resolved.startsWith('http')) continue;
    const name = path.slice(path.lastIndexOf('node_modules/') + 'node_modules/'.length);
    result.set(`${name}@${entry.version}`, { name, version: entry.version });
  }
  return [...result.values()];
}

// Returns only packages that are new or have a different version in the new lockfile.
export function changedPackages(base: LockedPackage[], head: LockedPackage[]): LockedPackage[] {
  const known = new Set(base.map((p) => `${p.name}@${p.version}`));
  return head.filter((p) => !known.has(`${p.name}@${p.version}`));
}

Step 3: Calculate the age and collect violations

The actual rule lives in a pure function. It receives the source of the date as a function argument. This lets you test it without a network. Exclusions work like in npm: exact names or a scope with /*.

// src/release-age.ts
import type { LockedPackage } from './lockfile.ts';

export type PublishTimeLookup = (pkg: LockedPackage) => Promise<Date | undefined>;

export interface AgeViolation {
  pkg: LockedPackage;
  ageDays: number | undefined; // undefined = the registry has no publish date
}

export interface AgeCheckOptions {
  minDays: number;
  exclude: string[]; // package names or patterns like "@bookshop/*"
  now?: Date;
}

const DAY_MS = 24 * 60 * 60 * 1000;

export function isExcluded(name: string, patterns: string[]): boolean {
  return patterns.some((pattern) =>
    pattern.endsWith('/*') ? name.startsWith(pattern.slice(0, -1)) : name === pattern,
  );
}

export async function findTooYoung(
  packages: LockedPackage[],
  lookup: PublishTimeLookup,
  options: AgeCheckOptions,
): Promise<AgeViolation[]> {
  const now = options.now ?? new Date();
  const candidates = packages.filter((pkg) => !isExcluded(pkg.name, options.exclude));
  const checks = await Promise.all(
    candidates.map(async (pkg) => {
      const published = await lookup(pkg);
      if (!published) return { pkg, ageDays: undefined };
      const ageDays = (now.getTime() - published.getTime()) / DAY_MS;
      return { pkg, ageDays };
    }),
  );
  // A missing date counts as a violation: better to look once too often
  return checks.filter((c) => c.ageDays === undefined || c.ageDays < options.minDays);
}

Step 4: Query the registry

For each package the script loads the metadata exactly once, even if several versions of it appear in the lockfile. Scoped names such as @bookshop/prices need an encoded / in the URL. If your team uses its own registry, pass it with --registry.

// src/registry.ts
import type { LockedPackage } from './lockfile.ts';

interface Packument {
  time?: Record<string, string>;
}

// Asks the registry for the publish date of exactly this version.
export function createRegistryLookup(registry = 'https://registry.npmjs.org') {
  const cache = new Map<string, Promise<Packument>>();
  const base = registry.replace(/\/$/, '');

  const load = (name: string): Promise<Packument> => {
    let pending = cache.get(name);
    if (!pending) {
      const url = `${base}/${name.replace('/', '%2F')}`;
      pending = fetch(url, { headers: { accept: 'application/json' } }).then(async (res) => {
        if (!res.ok) throw new Error(`Registry answered ${res.status} for ${name}`);
        return (await res.json()) as Packument;
      });
      cache.set(name, pending);
    }
    return pending;
  };

  return async (pkg: LockedPackage): Promise<Date | undefined> => {
    const doc = await load(pkg.name);
    const iso = doc.time?.[pkg.version];
    return iso ? new Date(iso) : undefined;
  };
}

Step 5: The command line script

The script reads the minimum age from the .npmrc, so there is only one source of truth. You can override it with --min-days.

// src/cli.ts
import { readFileSync, existsSync } from 'node:fs';
import { parseArgs } from 'node:util';
import { readLockedPackages, changedPackages } from './lockfile.ts';
import { findTooYoung } from './release-age.ts';
import { createRegistryLookup } from './registry.ts';

const { values } = parseArgs({
  options: {
    base: { type: 'string' }, // lockfile from the target branch, e.g. from git show
    head: { type: 'string', default: 'package-lock.json' },
    'min-days': { type: 'string' },
    exclude: { type: 'string', multiple: true, default: [] },
    registry: { type: 'string', default: 'https://registry.npmjs.org' },
  },
});

// Without --min-days, the value from the project .npmrc applies
function minDaysFromNpmrc(): number | undefined {
  if (!existsSync('.npmrc')) return undefined;
  const match = readFileSync('.npmrc', 'utf8').match(/^\s*min-release-age\s*=\s*(\d+)/m);
  return match ? Number(match[1]) : undefined;
}

const minDays = Number(values['min-days'] ?? minDaysFromNpmrc() ?? 3);
const head = readLockedPackages(readFileSync(values.head, 'utf8'));
const base = values.base ? readLockedPackages(readFileSync(values.base, 'utf8')) : [];
const toCheck = changedPackages(base, head);

console.log(`Checking ${toCheck.length} new or changed packages (minimum age ${minDays} days)`);

const violations = await findTooYoung(toCheck, createRegistryLookup(values.registry), {
  minDays,
  exclude: values.exclude,
});

for (const { pkg, ageDays } of violations) {
  const age = ageDays === undefined ? 'without a date' : `${ageDays.toFixed(1)} days old`;
  console.error(`βœ— ${pkg.name}@${pkg.version} is ${age}`);
}

if (violations.length > 0) {
  console.error(`${violations.length} package(s) younger than ${minDays} days – please review the lockfile.`);
  process.exit(1);
}
console.log('βœ“ All new versions have passed the waiting period.');

Step 6: Test it

The tests use Node’s built-in test runner. Two commands are enough for type checking and testing:

// test/release-age.test.ts
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { readLockedPackages, changedPackages } from '../src/lockfile.ts';
import { findTooYoung, isExcluded } from '../src/release-age.ts';

const lock = (packages: Record<string, object>) =>
  JSON.stringify({ lockfileVersion: 3, packages: { '': { name: 'bookshop' }, ...packages } });

const reg = (name: string, v: string) => ({
  version: v,
  resolved: `https://registry.npmjs.org/${name}/-/${name.split('/').pop()}-${v}.tgz`,
});

test('reads nested and scoped packages from the lockfile', () => {
  const pkgs = readLockedPackages(
    lock({
      'node_modules/zod': reg('zod', '4.1.0'),
      'node_modules/@bookshop/prices': reg('@bookshop/prices', '2.0.0'),
      'node_modules/a/node_modules/zod': reg('zod', '3.25.0'),
      'packages/catalog': { version: '1.0.0' },
    }),
  );
  assert.deepEqual(
    pkgs.map((p) => `${p.name}@${p.version}`).sort(),
    ['@bookshop/[email protected]', '[email protected]', '[email protected]'],
  );
});

test('checks only new or changed versions', () => {
  const base = [{ name: 'zod', version: '4.1.0' }, { name: 'ky', version: '1.8.0' }];
  const head = [{ name: 'zod', version: '4.1.0' }, { name: 'ky', version: '1.9.0' }];
  assert.deepEqual(changedPackages(base, head), [{ name: 'ky', version: '1.9.0' }]);
});

test('reports versions that are too new or have no date', async () => {
  const now = new Date('2026-10-28T12:00:00Z');
  const published: Record<string, string | undefined> = {
    '[email protected]': '2026-10-27T12:00:00Z', // 1 day old
    '[email protected]': '2026-10-01T12:00:00Z', // 27 days old
    '[email protected]': undefined,
  };
  const pkgs = Object.keys(published).map((key) => {
    const [name, version] = key.split('@');
    return { name, version };
  });
  const violations = await findTooYoung(
    pkgs,
    async (p) => {
      const iso = published[`${p.name}@${p.version}`];
      return iso ? new Date(iso) : undefined;
    },
    { minDays: 3, exclude: [], now },
  );
  assert.deepEqual(
    violations.map((v) => [v.pkg.name, v.ageDays]),
    [['ky', 1], ['mystery', undefined]],
  );
});

test('exclusions apply to names and scopes', () => {
  assert.equal(isExcluded('@bookshop/prices', ['@bookshop/*']), true);
  assert.equal(isExcluded('@bookshopx/prices', ['@bookshop/*']), false);
  assert.equal(isExcluded('zod', ['zod']), true);
});
npm install
npm run typecheck
npm test

Expected result: four green tests. Against the real registry, the run in my test project with the nightly build looked like this:

Checking 8 new or changed packages (minimum age 3 days)
βœ— @typescript/[email protected] is 0.1 days old
βœ— @typescript/[email protected] is 0.1 days old
βœ— [email protected] is 0.1 days old
…
8 package(s) younger than 3 days – please review the lockfile.

The second run with --exclude typescript is interesting: afterwards seven violations remained, namely the platform-specific packages that TypeScript 7 brings along. An exclusion only applies to the named package, not to its dependencies. The npm docs describe min-release-age-exclude the same way.

Step 7: Add it to GitHub Actions

The workflow only runs when a pull request changes the lockfile. It fetches the version from the target branch and passes it in as the baseline. The check itself does not need npm install.

# .github/workflows/release-age.yml
name: release-age
on:
  pull_request:
    paths:
      - package-lock.json
permissions:
  contents: read
jobs:
  lockfile-age:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v7
        with:
          node-version: 24
      - name: Fetch the lockfile from the target branch
        run: git show "origin/${{ github.base_ref }}:package-lock.json" > "$RUNNER_TEMP/base-lock.json"
      - name: Check the age of new package versions
        run: node tools/release-age-guard/src/cli.ts --base "$RUNNER_TEMP/base-lock.json" --exclude "@bookshop/*"

Two security notes: the workflow only needs read permissions, and in a real project you should pin the actions to a commit hash instead of a tag. The cost is negligible, a run takes a few seconds. Only very large packages have metadata of several megabytes, which is why the script only queries changed packages. Since late October 2026 there is a more readable way: I show how the GitHub Actions lockfile separates tags from commits in a separate article.

Dependabot cooldown and Renovate minimumReleaseAge

The update bots are the second layer. They make sure that no pull request with a brand-new version is created in the first place, and they are the reason the lockfile check rarely fires in everyday work.

Dependabot

According to the current GitHub docs, Dependabot already applies a three-day waiting period to version updates by default. With the cooldown block you can fine-tune it, separately for major, minor and patch updates. Security updates are explicitly excluded and arrive immediately.

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    cooldown:
      default-days: 3
      semver-major-days: 14
      semver-minor-days: 7
      semver-patch-days: 3
      exclude:
        - "@bookshop/*"

Renovate

Renovate calls the option minimumReleaseAge and expects a duration as text. As long as a version is too new, Renovate does not create a branch at all with the default setting internalChecksFilter: "strict". When generating the npm lockfile, Renovate also passes --before itself, so indirect dependencies are not too fresh either. Here, too, security updates bypass the waiting period.

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["config:recommended"],
  "minimumReleaseAge": "3 days",
  "packageRules": [
    { "matchUpdateTypes": ["major"], "minimumReleaseAge": "14 days" },
    { "matchPackageNames": ["@bookshop/**"], "minimumReleaseAge": null }
  ]
}

Since Renovate 42, a missing timestamp counts as β€œnot old enough yet”. For npm this is not an issue, but with some container registries Renovate holds back digest updates indefinitely as a result. My rule of thumb for both bots: the waiting period in the bot is at least as long as the one in the .npmrc. Otherwise you get pull requests that could not even be reproduced locally with a fresh install.

GitHub package firewall for larger organizations

On October 20, 2026, GitHub released the package firewall as a public preview. It sits between your machines and the npm registry and checks both metadata requests and downloads against policies that administrators define for the whole enterprise. These include a configurable waiting period, checks against the GitHub Advisory Database for malware and vulnerabilities, and checks such as a downgrade in attestations. If the firewall blocks a package by mistake, developers can request an exception.

The limitations are clear: so far it only supports npm and is only available to GitHub Enterprise Cloud customers. It is free during the preview and is supposed to be billed by usage afterwards. I mainly see its appeal for agents and CI runners whose configuration you do not control in every repository. For a single team it does not replace the three configuration files from this article; it complements them.

How long should the cooldown be?

My recommendation to start with: three days in the package manager, and in the bot three days for patches, seven for minor and 14 for major updates. The three days are not arbitrary. The npm registry allows authors to unpublish a package within 72 hours of publishing it. If you wait three days, you no longer install a version that might still disappear at short notice. Majors get more time because they mean work anyway and an extra week rarely matters.

I often hear two objections. The first: β€œIf everyone waits, who will find the malicious version?” In the well-known cases from 2025, it was mostly the automated scanners of security companies that raised the alarm first, since they analyze every new version right away. The early installers were victims rather than discoverers. Still, the objection is not entirely unfounded, so I would not go up to several weeks. The second objection: β€œThen security fixes arrive too late.” For the bots that is not true, because security updates bypass the waiting period. Locally you need the deliberate exception path from step 3.

Where I clearly disagree: a cooldown is no substitute for other measures. It does not help against packages that have been malicious for a long time, nor against install scripts of packages you trust anyway. A committed lockfile, npm ci in the pipeline, install scripts only for approved packages and trusted publishing for your own packages remain mandatory. The cooldown only takes the most dangerous moment off your hands: the first day of a new version. How quickly such a moment can escalate is something I described in the article on the Node.js vulnerability Node2Shell, even though that one was a flaw in Node itself.

Common mistakes with an npm cooldown

  • Mixing up units: minimumReleaseAge: 3 in pnpm means three minutes. Add the unit as a comment.
  • Old npm version on the team: npm before 11.10 ignores the option without an error. Set the minimum version in engines and check it in CI.
  • Exclusion too broad: an entry in the exclusion list only applies to the name, not to its dependencies. For hotfixes, prefer a targeted --min-release-age=0 on the single command.
  • Missing timestamps: private registries or proxies do not always return a time field. pnpm waves such packages through by default; the lockfile check from this article reports them.
  • Only the .npmrc, no check: without a CI check, new versions slip through existing lockfiles, see above.

If you are working on your review process anyway: bot PRs with dependency updates combine well with the ideas from my post on AI-assisted code fixes with AWS Continuum.

FAQ

What is npm min-release-age?

An npm configuration option that defines how many days old a package version must be before npm installs it. Newer versions are skipped during resolution.

Which npm version introduced min-release-age?

The option arrived with npm 11.10.0 in February 2026. The exclusion list min-release-age-exclude has been available since npm 12.

Does min-release-age apply to npm ci?

No. npm ci installs exactly what the lockfile says. In my test, npm install with an existing lockfile also ran without an age check. That is why checking new lockfile entries in CI is worth it.

Does a cooldown delay security updates?

Not with Dependabot and Renovate; both exclude security updates. Locally and in the pipeline you need a deliberate exception path, for example --min-release-age=0 for exactly one command.

Your next step

Open your most important repository, check the version with npm -v and create the two-line .npmrc from step 1. That takes five minutes. You can add the lockfile check afterwards at your own pace. And now I am curious: how long is the waiting period on your team, and have you ever missed a hotfix because of a cooldown? Feel free to tell me in the comments.

Sources

This post was created with AI assistance.

πŸ‘‰ Next step: Not sure which AWS service fits your use case? My AWS service finder asks a few questions and points you to the right one.

Originally published on sascha-ms.de. More articles on serverless, AI in everyday development and leading tech teams: sascha-ms.de/en

πŸ“° Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.