There is no correct number, but there should be a budget. Decide how many direct dependencies your CLI may have, require a written reason for each addition, and track transitive packages too. Every package is code that runs on your users' machines, often next to credentials.
Why a CLI is a special case
A web app's dependencies run on your servers. A CLI's dependencies run on every user's laptop and CI runner, in whatever directory they happen to be in, with the user's permissions. If one dependency is compromised, so is every machine that runs your latest release.
That is also why a CLI is a good place to be strict. The tool has a narrow job, and a narrow job rarely needs a large tree.
Direct versus transitive
You choose direct dependencies. They choose theirs. A single direct package can bring in dozens more. Count both numbers and record them at each release.
| What to count | Why |
|---|---|
| Direct dependencies | Decisions you made, each one needs a reason |
| Transitive dependencies | Code you did not choose, and the main source of surprise |
| Distinct maintainers | Each is an account that could be taken over |
| Packages with install scripts | Code that runs at install, before anyone reviews it |
How to set a budget
- Count today. Run an inventory and write down the four numbers above.
- Pick a ceiling for direct dependencies. Base it on your current count, then aim lower over time.
- Add a review step. A pull request that adds a dependency must say what it does, what the alternative is, and who maintains it.
- Prefer the standard library. For small tasks such as argument parsing helpers or colour output, a few lines of your own code beat a package.
- Remove before you add. If a new package overlaps with an old one, drop the old.
- Check the tree in CI. Fail the build if the transitive count jumps by more than an agreed amount, and let a human approve it.
Try it yourself
Open the demo and read the inventory view. Notice how the direct list is short and the full list is long.
Click through it at your own pace, or open it full screen.
What not to do
Do not chase a low number by copying a package's code into your repository and forgetting about it. That hides the dependency from scanners and stops it receiving fixes. If you vendor code, record where it came from and its version, and review it on a schedule.
Quick check
Is fewer dependencies always safer?
Usually, but not automatically. A well maintained library can be safer than hand-written code for hard problems such as parsing or cryptography. Budget for what you can review.
Do transitive dependencies matter if I trust my direct ones?
Yes. A compromise anywhere in the tree reaches your users. Track the full list at every release.
Safeguard's SBOM and dependency scanning list direct and transitive packages, and a free scan is available at gold.safeguard.sh/scan.
Last reviewed: 19 October 2026.