PLAINFINCH learn by building

Dependencies and updates

You will find a package with a published hole, update it, and learn to spot a package name that does not exist.

What is a dependency?

A dependency is code someone else wrote that your site uses. The bakery's package.json lists four: express to answer requests, escape-html to make visitor text safe, dompurify to clean HTML, and @pretend/markdown to turn staff notes into HTML. When you run npm install, npm downloads each one into node_modules, along with everything those packages need in turn.

Those second-level packages add up. A small Express site with a handful of direct dependencies often ends up with a hundred or more packages in node_modules. You did not choose most of them and you will never read them, yet every one runs with the same access as your own code.

That is a reasonable trade. Writing your own web server or HTML escaper would take far longer and would probably have more bugs. The cost is that you now need a habit for keeping all that borrowed code current.

Figurepackage.json lists four packages. npm install pulls in each one plus the packages they need. @pretend/markdown 3.1.0 is marked with an advisory that is fixed in 3.2.1.package.json lists four packages. npm install pulls in each one plus the packages they need. @pretend/markdown 3.1.0 is marked with an advisory that is fixed in 3.2.1.
You choose a few packages and each one brings its own. An advisory on any of them, like the one on @pretend/markdown 3.1.0, becomes your problem until you update.

What is a security advisory?

When someone finds a security hole in a package, the maintainers fix it and publish a new version. An advisory is the public notice that goes with it: which package, which versions are affected, what the problem is, and which version fixes it. GitHub keeps a large database of these, and npm audit reads from it.

Advisories help defenders and attackers equally. The moment one is published, anyone can read that @pretend/markdown before 3.2.1 lets a script through inside link text, and go looking for sites still on 3.1.0. The lab's Known hole in a package attack plays that part.

Every popular package has had bugs. The danger lies in old versions that still contain a bug the whole world now knows about. The sites that get hurt are the ones still running the version from two years ago.

How do you check your own packages?

Run npm audit in the project folder. It compares the exact versions in your lock file against the advisory database and lists each problem with a severity and the fixed version. npm audit fix updates whatever it can without a major version jump. npm outdated shows every package with a newer version, security issue or not.

If your code lives on GitHub, turn on Dependabot alerts in the repository settings. GitHub then emails you when a new advisory affects one of your packages, and Dependabot can open a pull request that bumps the version. GitLab and other hosts have similar features.

After an update, run your site and click through the pages that use the package. Patch and minor updates rarely break anything, but a major version, for example 4 to 5, can change how a package is called. Read its release notes first.

npm audit            # list known problems
npm audit fix        # apply safe updates
npm outdated         # see everything that has a newer version

What do the version numbers mean?

Most packages use three numbers: major, minor and patch, as in 3.2.1. A patch release fixes bugs, a minor one adds features without breaking anything, and a major one may break existing code. Security fixes usually arrive as patch or minor releases, which is why they are normally safe to take quickly.

In a real package.json you usually see ranges such as ^3.1.0, which means any 3.x version from 3.1.0 up. The exact versions installed are recorded in package-lock.json. Commit the lock file, so your laptop and your server run the same code, and use npm ci on the server to install exactly what it lists.

What is a made-up package, and why is it dangerous?

AI assistants sometimes recommend packages that do not exist. The name sounds right, such as bakery-safe-forms or express-password-check, and the code that uses it looks plausible. If you run npm install on a name nobody has registered, you get an error and no harm is done.

The danger comes when someone registers it first. Attackers collect the names that AI tools tend to invent and publish packages under them with harmful code inside, often in an install script that runs the moment npm installs it. This trick is sometimes called slopsquatting. A similar trick uses names one typo away from popular packages.

Before installing any name you do not recognise, look it up on npmjs.com. Check that it has a real repository link, a history of releases, more than a handful of weekly downloads, and a maintainer you can see. If any of that is missing, do not install it. The lab's Package that does not exist attack checks only whether a name is in its small pretend registry.

How many dependencies should you have?

Fewer is easier to keep safe. Before adding a package, ask whether a few lines of your own would do. Padding a string or checking that a field is a number does not need a package. Escaping HTML, hashing passwords and parsing cookies do, because those are easy to get subtly wrong.

Prefer packages that many sites use, that had a release in the last year, and that have few dependencies of their own. Remove packages you stopped using; npm uninstall takes them out of both package.json and the lock file. The fewer names on the list, the less work each advisory creates.

What do AI tools get wrong about dependencies?

Beyond invented names, assistants often suggest versions from their training data, which may be a year or more out of date and may have known advisories. They recommend packages that have since been deprecated, such as csurf for CSRF tokens, which its maintainers retired in 2022. They also reach for a package when a few lines would do.

When an assistant adds a dependency, check three things: the name exists and is the package you think it is, the version is current, and there is no notice on its npm page saying it is deprecated. Then run npm audit after installing.

Where does the lab simplify?

The lab reads the version in package.json as if it were the installed version and ignores ^ and ~. Real installs follow the lock file. The three advisories are pretend, attached to packages under the made-up @pretend/ scope, so no real package is accused of anything. The lab also only knows a short list of real package names; a real registry has millions, and a name being registered tells you nothing about whether the code inside is safe.

Field notes

  • A security advisory is a public notice of a hole in a package version.
  • npm audit lists advisories for your packages, and npm audit fix applies safe updates.
  • In ^3.1.0, the caret allows minor and patch updates but not a new major version.
  • Check that a package an AI suggests exists and is the one you meant before you install it.

Easy to get wrong

New advisories appear for old versions every week. A check that never repeats misses all of them.

Invented package names can be registered by attackers. A quick check shows whether a package is real, maintained and widely used.

Without the lock file, each install can pick different versions, so the server may run code you never tested.

Questions people ask

Should I update every package the moment a new version comes out?

Security fixes, yes, within days. Ordinary feature releases can wait for a calm moment when you can test. Major versions need reading the release notes first.

npm audit shows dozens of warnings. Where do I start?

Start with high and critical issues in packages your site uses while running. Warnings in development tools such as test runners can usually wait, because that code never runs for visitors. It does still run on your own machine, where your keys live, so do not ignore them for months.

Is a package with millions of downloads always safe?

It is far less likely to be invented, and problems in it are found faster. It can still have advisories, which is why you keep it updated. Popular packages are also targets: in September 2025 attackers took over a maintainer's npm account and published harmful versions of chalk and debug, which were removed within hours. A committed lock file means you only get a new version when you choose to update.

What does deprecated mean on npm?

The maintainers have stopped working on it and usually suggest a replacement. It will not get security fixes, so move off it when you can.

Keep going