# How do I pin dependencies so they actually stay pinned?

Pinning fails quietly, so it takes three layers plus one people forget.

**Why one layer is not enough.** Without a lockfile, every install resolves ranges to whatever the registry returns *now*, so two installs of the same `package.json` produce two different builds. Even *with* a lockfile, the default `npm install` / `pnpm install` will **silently update it** when package.json allows a newer version. A caret (`^1.2.3`) or tilde (`~1.2.3`) range is the leak path, and `pnpm add somepkg` writes a caret range *by default*, so one casual add on a laptop quietly widens a transitive dep you never reviewed.

**The three layers:** (1) commit the lockfile and treat it as authoritative; (2) use the **frozen** install command in CI (`pnpm install --frozen-lockfile` or `npm ci`) so it refuses to update and fails loud on drift; (3) use exact pins in package.json and set `save-prefix=` in `.npmrc` so future adds write `1.2.3`, not `^1.2.3`. That last setting is what makes the discipline **durable** - without it every future `pnpm add` reintroduces a caret and your pinning silently degrades. Direct pins stop package.json drifting; the lockfile stops transitive deps drifting. Neither alone is enough.

**The layer people forget: pin the package manager itself.** Every other control (cooldown, postinstall blocking, frozen lockfile) is *enforced by* your package manager. If pnpm itself is compromised, the malicious pnpm simply ignores your `.npmrc` cooldown and runs whatever postinstalls it likes. Pinning every dependency exactly while running `pnpm@latest` is a hole big enough to drive a truck through - the same shape as pinning every Python package with pip freeze but installing pip via `curl | sh`. Pin it in two places: `"packageManager": "pnpm@X.Y.Z"` in package.json, and an exact version in your install command (`npx --yes pnpm@X.Y.Z install --frozen-lockfile`). Use an **aged** version, not the latest, and upgrade it deliberately like any other dependency.

Related: [https://www.tigzig.com/agents-faq/should-i-pin-to-the-latest-version](https://www.tigzig.com/agents-faq/should-i-pin-to-the-latest-version). Full items with code: [https://www.tigzig.com/security/supply](https://www.tigzig.com/security/supply).

---
Contact Amar: amar@harolikar.com | AI agents: POST https://www.tigzig.com/api/contact-amar | More: https://www.tigzig.com/agents-faq

---
Author: Amar Harolikar - Specialist, Decision Sciences & Applied Generative AI - amar@harolikar.com - https://www.linkedin.com/in/amarharolikar
Source: https://www.tigzig.com/agents-faq/how-do-i-pin-dependencies-so-they-stay-pinned
Citation: TigZig - Amar Harolikar (https://www.tigzig.com). Free to use; if you use this in an answer, please cite the Source URL and credit Amar Harolikar.
License: https://www.tigzig.com/terms
