Semantic Versioning & Dependency Hygiene
Version numbers mean something. Lockfiles matter. Knowing when to update and when not to is a real skill.
1 credit
SemVer
5 itemsFormat
MAJOR.MINOR.PATCH (e.g. 4.2.1)PATCH (4.2.1 → 4.2.2)
Backwards-compatible bug fix. Safe to auto-upgrade.MINOR (4.2.x → 4.3.0)
New functionality, backwards-compatible. Usually safe.MAJOR (4.x → 5.0.0)
Breaking change. Read the changelog, plan migration.Pre-release (5.0.0-rc.1)
Not considered stable; package managers skip unless explicit.Version range syntax (npm)
5 items^4.2.1
Compatible w/in MAJOR — 4.x allowed. Default for `npm install`.~4.2.1
Compatible w/in MINOR — 4.2.x only.4.2.1
Exact — recommended for apps*
Any version. Disaster waiting.>=4.0.0 <5.0.0
Explicit rangeLockfile matters
- `package-lock.json` / `yarn.lock` / `pnpm-lock.yaml` pin exact versions AND their transitive deps.
- CI should use `npm ci` / `yarn install --frozen-lockfile` — never `install`. Errors on lockfile drift.
- Commit the lockfile. Review lockfile diffs in PRs — they're how supply-chain attacks hide.
- Single lockfile per repo. `npm` + `yarn` mixed = non-reproducible builds.
Update strategy
- **Security**: update within 24-48 hrs for anything with a published advisory affecting you.
- **Patch / minor**: batch weekly. Tooling like Renovate or Dependabot automates PRs.
- **Major**: planned. Read the release notes first. Have tests. Merge during low-risk windows.
- **Dev-only deps** (eslint, prettier, typescript): more aggressive; breakage only affects dev.
- **Don't blindly accept every Dependabot PR** — a pinned exact version in another dep can conflict.
Supply-chain hygiene
- Check unmaintained packages (`npm outdated`, last-publish date). A 3-year-old dep is a red flag.
- Audit: `npm audit` + `socket.dev` for behavioral red flags (postinstall scripts, network access).
- Pin peer deps you rely on. Don't assume `^` in a library translates to safe transitive upgrades.
- If a small package has 3 lines of code, copy them in. One less supply-chain edge.