lichens-innovation/ai-dev-tools

pin-exact-nodejs-dependencies

>- Pins exact dependency versions (no ^ or ~) via save-exact and npm-package-json-lint. Use when enforcing absolute versions in package.json, adding save-exact, preferring exact pins, or blocking caret/tilde ranges.

First seen Jul 28, 2026

Installation

$ npx skills add lichens-innovation/ai-dev-tools --skill pin-exact-nodejs-dependencies

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from lichens-innovation/ai-dev-tools · top by installs.

npx skills add lichens-innovation/ai-dev-tools

Browse all from lichens-innovation/ai-dev-tools

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

License LICENSE
Default branch main
Open issues 6
Status Active

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 3,662 B
  • docs SUMMARY.md 249 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

Pin exact dependencies

Recipe: prevent ^ / ~ in dependencies and devDependencies.

Detect package manager

Prefer in order:

  1. packageManager field in package.json (e.g. bun@…, pnpm@…, npm@…)
  2. Lockfile: bun.lock / bun.lockb → bun; pnpm-lock.yaml → pnpm; yarn.lock → yarn; package-lock.json → npm
  3. Default: bun

Use that PM for all install / script commands below. Map:

Action bun pnpm npm yarn
Add dev dep bun add -d <pkg> pnpm add -D <pkg> npm i -D <pkg> yarn add -D <pkg>
Run script bun run <script> pnpm run <script> npm run <script> yarn <script>

save-exact=true in .npmrc is respected by bun, npm, pnpm, yarn.

Steps

1. .npmrc — write exact on install

# Pin exact versions in package.json (no ^ / ~ ranges) when adding deps
save-exact=true

Prevents new ranges from package-manager add/install. Does not rewrite existing entries.

2. Fix existing ranges

Strip ^ / ~ from every dep in package.json, then refresh lockfile with the project PM. Lint fails until clean.

3. npm-package-json-lint — enforce

# bun (default):
bun add -d npm-package-json-lint
# pnpm: pnpm add -D npm-package-json-lint
# npm:  npm i -D npm-package-json-lint
# yarn: yarn add -D npm-package-json-lint

.npmpackagejsonlintrc.json:

{
  "rules": {
    "prefer-absolute-version-dependencies": "error",
    "prefer-absolute-version-devDependencies": "error"
  }
}

package.json scripts:

"lint:package": "npmPkgJsonLint ."

4. Wire git hooks (if present)

Detect before wiring:

  • Husky: .husky/ and/or husky in devDependencies / prepare script
  • Lefthook: lefthook.yml / lefthook.yaml and/or lefthook in devDependencies

Husky + lint-staged (common)

If lint-staged exists, add (run before generic *.json prettier if both match):

"package.json": ["npmPkgJsonLint", "prettier --write"]

Ensure pre-commit already runs lint-staged (e.g. .husky/pre-commitbun run lint-staged / pnpm exec lint-staged / npx lint-staged).

If husky without lint-staged: add npmPkgJsonLint . (or $PM run lint:package) to .husky/pre-commit.

Lefthook

In lefthook.yml (or .yaml), under pre-commit:

pre-commit:
  commands:
    lint-package:
      glob: "package.json"
      run: npmPkgJsonLint {staged_files}
      # or: <pm> run lint:package

Match existing lefthook style (parallel vs serial, root, etc.). Prefer glob-scoped run when other package.json-only checks exist.

Neither husky nor lefthook

Skip hooks. Rely on CI + manual lint:package. Do not add a hook tool unless the user asks.

5. Wire CI

After install, with other lints (substitute project PM):

- name: Lint package.json
  run: bun run lint:package
  # pnpm run lint:package | npm run lint:package | yarn lint:package

6. Verify

bun run lint:package   # or pnpm/npm/yarn equivalent

Must exit 0. Introduce a ^ temporarily only to confirm it fails, then revert.

Notes

  • Exact pins in package.json ≠ locked tree — lockfile still owns transitive versions.
  • save-exact = prevent; lint = catch hand-edits / leftovers.
  • Skip syncpack unless monorepo with many package.jsons.