‹ Ship Your Tool Lesson 6 of 16
Contents Lesson 6 of 16

4 min read · professional

What you actually installed

Before anything is public, look at what is in it. Most of your repository is code you did not write and have never read.

Eleven, and four hundred and thirty-four

Measured on the starter repository on 2026-08-26:

Declared dependencies 3
Declared dev dependencies 8
Packages in the lockfile 434

Eleven decisions, four hundred and thirty-four packages. That ratio is normal for this ecosystem and it is worth sitting with, because every one of those 434 runs with the same permissions as your code, and several of them run at install time.

This is not an argument for writing everything yourself. It is an argument for knowing the number, which almost nobody does.

Run the audit, and read it properly

npm audit on every push, and read the output with three questions:

Is it reachable? A vulnerability in a dev-only tool that never touches a request is a different risk from one in your HTTP path. --omit=dev separates them, and the difference is usually most of the list.

Is there a fix? npm audit fix handles most, and the ones it cannot are the ones that need a decision.

What does the decision cost? Sometimes the fix is a major version and half a day. That is a legitimate trade to make deliberately and record — not one to make by ignoring the output for six weeks.

Commit the lockfile, and know why

package-lock.json is committed. Without it, "the same code" installs different versions on your machine and in CI, and a bug that only appears in one of them is very hard to reason about.

With it, npm ci installs exactly what the lockfile says. Use npm ci in CI and npm install locally — the first is reproducible and fails on a mismatch, the second updates the lockfile, and using the wrong one in the wrong place is how a dependency drifts in without a diff.

Before adding a dependency, ask what it replaces

One question, applied honestly: is this more code than I would write?

A date library replacing twenty lines is a good trade. A package that formats a percentage is a supply chain you took on to avoid toFixed. The version of this that actually bites is not one obvious mistake; it is thirty small conveniences, each defensible alone.

Your assistant will suggest dependencies readily, because that is what most code it has read does. It is the right moment to apply course 1's habit of reading what you were handed and asking what a line actually buys.

Try it now

Count your own two numbers — declared versus lockfile — and put them in the README's architecture section. Then run the audit with and without --omit=dev and see how much of the list is not actually reachable from a request.