Nobody picks their dependency tree. You choose a handful of packages, each of those chooses its own, and a few layers down you are shipping code under terms you have never read, written by people you will never meet.

We counted what this site actually installs: 302 packages, resolved against the registry for the exact version in the lockfile.

Seventeen distinct licences. We chose none of them.

The distribution

LicencePackagesShare
MIT20467.5%
ISC3912.9%
Apache-2.0144.6%
MPL-2.0124.0%
LGPL-3.0-or-later103.3%
OFL-1.141.3%
BSD-3-Clause41.3%
Apache-2.0 AND LGPL-3.0-or-later31.0%

Four in five packages are MIT or ISC, which is the permissive, do-what-you-like end and the reason most teams never think about this. The interesting material is the tail.

Twenty-three packages with copyleft obligations

23 of the 302 carry strong copyleft terms — LGPL or MPL. These are not viral in the way internet arguments suggest, but they do carry obligations that MIT does not: broadly, if you distribute modified versions of the covered component, you have to make that source available under the same terms.

The striking part is where they came from. Effectively all 23 are the sharp image-processing family and its bundled libvips binaries — one image library, pulled in transitively, arriving with LGPL terms attached across a dozen platform-specific packages.

Nobody sat down and decided to take on LGPL obligations. Somebody wanted to resize images.

For most web applications this is fine: you are using the library, not distributing a modified version of it, and the obligation does not bite. But "fine" is a conclusion you can only reach if you know the packages are there in the first place—the very thing a dependency tree obscures.

Six packages that do not have a licence — they have an expression

This is the finding most licence inventories get wrong, including the ones that produce a tidy pie chart.

Six packages declare something like:

Apache-2.0 AND LGPL-3.0-or-later AND MIT

That operator is AND. It means the package contains components under all three licences and you must satisfy all three sets of obligations simultaneously. It is not a choice, and it is not one licence with extra words.

The distinction matters because SPDX expressions also come in an OR form — (MIT OR Apache-2.0) — which is a choice, one you make and should record. Same syntax family, opposite meaning.

A tool that flattens either into a single label is producing a wrong answer with a clean interface. If your compliance report shows one licence per package, check whether the underlying data ever contained an operator.

The good news, stated plainly

Zero packages in this tree declare no licence at all. This is a good result. An undeclared package is the hardest case to resolve; with no licence, no permission is granted by default, leaving you to email a maintainer and hope for a reply.

Two hundred and ninety-six packages tell you what they are. Six tell you they are several things at once. None leaves you guessing.

The obligation almost nobody meets

The 204 MIT packages are the ones nobody worries about, and they are also the ones carrying the most widely ignored requirement in open source.

MIT is not public domain. It grants broad permission on one condition: the copyright notice and permission text must be included in copies or substantial portions of the software. If you bundle those 204 packages into a JavaScript file and serve it, you are distributing them, and the notices are supposed to travel too.

Almost nobody does this by hand, and almost nobody needs to — the tooling exists. Bundler plugins that collect licence text into a single file are a few lines of configuration, and the output is the attribution page that most sites either have buried somewhere or do not have at all.

We are not going to pretend this is an urgent risk; the practical consequence of omitting it is close to nil for most projects. It is worth knowing because it is the one obligation that applies to two thirds of the tree rather than the exotic tail, and because the fix is a build step rather than a legal conversation.

The four OFL-1.1 packages in our tree are fonts, and font licences are the other place this bites: OFL has its own conditions about redistribution and renaming that are unlike anything in the software licences around them.

How to check yours

The registry knows, for any exact version:

npm view [email protected] license

Across a whole tree, npm ls --json plus a pass over the registry will do it, which is essentially what our script does. The three things worth extracting are the ones above: the distribution, anything with copyleft terms, and anything whose licence field contains AND or OR rather than a single identifier.

Then read the tail, not the headline. A tree dominated by MIT isn't free of obligations. It just means the obligations are concentrated in a handful of packages, which makes a review much more manageable than it sounds.

The same tree has two other properties a lockfile will not volunteer: how old the code is — one package in five has had no release in two years — and whether any of it can prove where it came from, which is 10.8% of what we ship to users.

What this measurement is not

This is not legal advice, and the numbers above are not a compliance position. We counted declarations.

Three specific limits follow from that. The registry reports what the publisher declared, which can disagree with the LICENSE file in the repository — where they conflict, the file generally governs and the field is a summary someone typed. A declared licence also says nothing about whether the package has the right to grant it; vendored code inside a package can carry terms of its own that never surface in the metadata. And this counts packages, not use: whether an obligation actually applies depends on what you do with the code, and distributing a modified library is a different act from running one on a server.

What the measurement gives you is a starting list: seventeen licences, twenty-three with copyleft terms, and six that are expressions. It's a list you can generate in about a minute, and one you won't have at all if you don't look.

The companion measurement, what a package signature actually proves, covers the other thing a lockfile does not tell you: where the code came from. Figures are from 19 August 2026 and the script is in our repository — the useful version of this exercise is the one you run against your own tree.