Adding Dependencies

作者 riekelte67b7af9ac74無授權條款5 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫3 週前更新

Use when about to add, update, vet, or remove a dependency - a package, library, SDK, GitHub action, base image, or vendored code - or when a project's dependency posture needs declaring. Encodes the exhaust-what-you-have ladder, the vetting questions, and pin-and-prove updating. Use even for a tiny utility package: that is exactly how the tree grows.

AI 產生的概覽

指導判斷是否新增、審查、鎖定、更新或移除軟體相依性,以及如何宣告相依性策略。

功能
提供一套決策階梯,要求在引入新套件之前先窮盡現有程式碼、標準函式庫、平台能力和專案已攜帶的相依性。它列出審查問題,涵蓋傳遞相依成本、授權條款、安全歷史、維護者活躍度和 API 表面,並要求記錄該決策。它也涵蓋鎖定版本與鎖定檔、測試更新,以及移除已失去用途的相依性。
適用情境
適用於即將新增、更新、審查或移除相依性(例如套件、函式庫、SDK、GitHub action、基礎映像或內嵌程式碼)時。也適用於需要宣告或質疑專案相依性策略時。
執行需求
僅為說明性內容,不含指令碼。它引用其他技能(principal-engineering、recording-decisions、testing-changes、keeping-one-source-of-truth)作為背景,並假定可存取專案規則或 CLAUDE.md 以確定策略。

Adding dependencies

REQUIRED BACKGROUND: the principal-engineering skill.

Overview

A dependency is a hire, not a snippet: with the feature come its defects, its release rhythm, its transitive tree, and its maintainer's attention span. Core principle: exhaust what you already have, vet what you take, pin what you took, and record why.

Exhaust what you already have

Work down the list and stop at the first level that holds; good answers often compose two levels, an existing dependency for the hard part with a few lines of your own around it:

  1. The need itself. Speculative need is no need; skip it and say so in a line.
  2. This codebase. A helper, type, or pattern a few files away does the job; reuse it. A second copy of something the repo already contains is the defect keeping-one-source-of-truth bans for data.
  3. The standard library. Read its index before installing a package that duplicates it.
  4. The platform. A database constraint over application code, a native control over a widget library, the runtime's own primitive over a wrapper.
  5. A dependency the project already carries. Its transitive tree is already paid for. Two boundaries. A transitive you start using is a NEW direct dependency: declare it, pin it to the already-resolved version, and vet it lightly since the code already ships. Check the class the reuse crosses: a dev-tool's transitive promoted into runtime shifts the cost to every consumer's install, not just CI.
  6. A few lines of your own. Owning twenty lines beats owning a stranger's repository, when twenty lines is truly all it takes.
  7. Only past all six: a new dependency, vetted below.

Vetting the one you take

  • Cost the whole hire: the transitive tree it drags in, the install and build weight, the license against the project's, the security history (advisories, and a supply-chain score where a scanner runs).
  • Check the pulse: recent releases, how issues get answered, how many people can merge. A load-bearing package with one exhausted owner is a risk you are choosing.
  • Read the part you will call: the API surface you depend on and its failure modes, not the README's promises. Grounding applies to other people's code too.
  • Prefer the tool with one job over the framework with forty; the other thirty-nine come along anyway, in weight and in attack surface.
  • Record the decision. A new dependency is a decision: what it is for, what else was weighed, and the condition under which it leaves (via recording-decisions where installed).

Dependency posture

Dependency tolerance is the project's to declare, like its risk tiers: fully self-contained (some apps rightly ban external code wholesale), a curated allowlist, or vet-and-add. The project's rules or CLAUDE.md state which; when nothing does, ask what the system must never depend on and treat the answer as the declaration. A posture is honored even when inconvenient; changing it is a recorded decision, not an npm install.

An undeclared posture is not a hard gate: when nobody can answer today, proceed under a stated assumed posture, record the assumption in the decision, and track the declaration question with an owner.

Pin and prove

  • Commit lockfiles and pin versions; an unpinned latest in CI or a base image is a time bomb with someone else's clock.
  • An update is a change like any other. Read the release notes BEFORE a major bump (breaking changes and migrations first). Run the tests against it (testing-changes). Give a major bump its own commit so the blame trail stays readable; grouped patch bumps may travel together.
  • Vendored code carries its origin and version in the tree; you cannot update what you cannot date.

Removal

  • A dependency whose job disappeared leaves in the same change that removed the job; a package kept "in case" is the speculative need from level 1, in reverse.
  • When the dependency is down to one small call site, consider owning those lines instead.
  • Unmaintained but load-bearing is a risk item with an owner and a plan, never a hope.

Common mistakes

  • The tiny-utility reflex: trees do not grow by big decisions; they grow one small package at a time, each individually reasonable.
  • A framework installed to call one function.
  • Depending on a package's internals or private paths; only the public contract is a promise.
  • Importing a transitive dependency as if it were yours: undeclared today, gone on the next lockfile refresh. If you need it, declare it.
  • Adding a dependency to avoid reading the code already in the repo (level 2, skipped).
  • Vendoring without provenance, then wondering which version the copy was.
  • Updating everything at once, then bisecting to find which bump broke the build.

來源與署名

來源:riekelt/principal-engineer位於plugins/principal-engineer/skills/adding-dependencies提交e67b7af

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架