Dependency Rules
Dependency rules keep install graphs small, auditable, and maintained so production services do not inherit abandoned or vulnerable packages.
Recipe
Quick-reference recipe card - copy-paste ready.
{
"dependencies": {
"fastify": "^5.0.0"
},
"scripts": {
"audit": "npm audit --audit-level=high"
}
}npm ci
npm audit --audit-level=highWhen to reach for this:
- Adding any npm dependency to a service or shared library.
- Weekly platform hygiene review.
- Incident response after supply-chain advisory.
Working Example
# docs/dependencies.md (in repo)
## Add a dependency (RFC-lite)
1. Need stated in PR description
2. Weekly downloads > 100k OR org-approved exception
3. Last publish < 12 months ago
4. No install scripts OR reviewed in PR diff
5. License MIT/Apache-2.0/ISC only for prod deps# .github/workflows/audit.yml
on:
schedule:
- cron: "0 6 * * 1"
pull_request:
paths: [package.json, package-lock.json]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm audit --audit-level=high// Prefer Node built-ins when sufficient
import { createHash, randomUUID } from "node:crypto";
// instead of adding `uuid` + `crypto-js` for basic needsWhat this demonstrates:
- PR checklist before new packages land.
- Scheduled weekly audit plus PR gate on lockfile changes.
- Built-in
node:cryptoavoids extra dependency for UUID/hash.
Deep Dive
How It Works
package.jsonranges allow compatible updates; lockfile pins exact versions.- Renovate/Dependabot opens tested upgrade PRs on schedule.
npm auditreports known CVEs on locked graph.- Abandoned packages accumulate unpatched CVEs and incompatible peer deps.
Version Pinning Policy
| Dep type | Range policy |
|---|---|
| Framework (express, fastify, nest) | Careful minor bumps, test suite |
Internal @acme/* | workspace or semver publish |
| Transitive | Controlled via lockfile only |
| devDependencies | Pin majors; update with toolchain |
TypeScript Notes
@types/*devDeps track DefinitelyTyped; remove when package ships own types (Express 5).- Align
@types/nodewith Node 24.
Gotchas
- Adding lodash for one function - 4MB dependency tax forever. Fix: native JS or 10-line util in
packages/utils. - Ignoring audit because "no fix" - Silent debt for months. Fix: exception ticket with compensating control and expiry.
- GitHub dependency on
masterbranch - Unpinned mutable source. Fix: semver release from npm or git tag SHA. - Duplicate overlapping libs -
momentanddate-fnsanddayjs. Fix: org standard date library one pick. - Install script packages without review - Supply-chain risk. Fix: block in Socket/PR policy.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Vendoring tiny MIT snippet | Single function, license clear | Large or GPL code |
| Private registry proxy | Cache and scan all tarballs | Solo hobby project |
| Zero-dep policy for libs | Published packages | Internal apps with normal deps |
FAQs
Pin exact versions in package.json?
Apps use ranges + lockfile. Libraries use ranges for consumers; avoid exact pins unless necessary.
How to detect abandoned packages?
Check last publish date, open issues, npm downloads; Socket flags unmaintained signals.
Can we use GPL dependencies?
Generally avoid in proprietary services; legal review required for copyleft.
How many direct dependencies is too many?
No fixed number; question each add. >50 direct deps warrants periodic knip and audit review.
Overrides field in package.json?
Use sparingly to force transitive patch; document reason in PR; overrides confuse Renovate.
Peer dependency warnings?
Fix before merge; Nest/ESLint plugins often need explicit peer installs.
Should workers share lockfile with API?
Monorepo: yes single root lockfile. Polyrepo: independent audits per deployable.
How fast to patch critical CVE?
SLA 24-48h for reachable RCE in HTTP stack; track in incident board.
Are devDependencies audited?
Yes for developer machine risk; also run npm ci --omit=dev audit for prod graph.
Replacing deprecated package process?
ADR or ticket, migration branch, remove old dep same PR as new implementation.
Related
- Node Project Rules Checklist - rule 10
- Supply Chain: npm audit & Socket - audit checklist
- Security Rules - app-layer security
Stack versions: This page was written for Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5, and NestJS 11.