License compliance guide
npm package license compliance: which open-source licenses are safe for commercial use
npm audit checks for CVEs. It checks nothing about licenses. An npm install that pulls in a single AGPL-licensed package can legally require you to open-source your entire application. Here is how to find every license in your dependency tree — and what to do when you find a risky one.
- Why license risk is different
- The npm license landscape
- The AGPL blind spot
- How to check all your licenses
- Transitive dependencies
- What to do with a risky license
- FAQ
Why license compliance is a separate audit from CVE scanning
A CVE is a bug — someone will publish a patch, you upgrade, the risk closes. A license is a permanent legal condition of the package. No advisory database tracks it. No future release fixes it. And unlike a security vulnerability, you can ship for years before the obligation surfaces — often during an acquisition due diligence, a customer security review, or a cease-and-desist from the package author.
The npm registry contains packages under hundreds of different licenses. The vast majority use permissive licenses (MIT, Apache-2.0) that impose almost no obligations. A small minority use copyleft licenses that, under the right conditions, require you to publish your application's source code under those same terms. The consequence of missing one is not a vulnerability score — it is a legal obligation you may have already violated.
The npm license landscape
There are three categories. The table below covers the licenses you are most likely to encounter:
| License | Type | Commercial use | Key obligation |
|---|---|---|---|
| MIT, ISC, BSD-2-Clause, BSD-3-Clause | Permissive | ✓ Safe | Include the license text in distributions |
| Apache-2.0 | Permissive | ✓ Safe | Preserve NOTICE file; includes explicit patent grant |
| CC0-1.0, Unlicense | Public domain | ✓ Safe | None |
| LGPL-2.1, LGPL-3.0 | Weak copyleft | ⚠ Use with care | Modifications to the library must be open-sourced; dynamic linking is usually safe, but JavaScript bundling blurs this line |
| GPL-2.0, GPL-3.0 | Strong copyleft | ✗ Risky | Distributing software that links GPL code requires distributing your app under GPL too |
| AGPL-3.0 | Network copyleft | ✗ Risky for web apps | Running AGPL code as a network service requires making your entire app's source available under AGPL |
| SSPL-1.0 | Commercial-open-source | ✗ Risky | Requires open-sourcing the full service infrastructure around the software; not OSI-approved |
| EUPL-1.2 | Copyleft | ⚠ Review required | Copyleft similar to LGPL; commonly used in EU public sector packages |
| Unlicensed / no license field | All rights reserved | ✗ No rights granted | You have no permission to use the package at all without contacting the author |
The AGPL blind spot — especially for AI/ML projects
The GPL's copyleft triggers when you distribute software — shipping a binary to end users. Running a GPL web app on your server is generally not distribution, so the GPL's obligations do not activate for a server-side web application. AGPL closes this gap with a single additional clause: if you run the software to provide a service over a network, users of that service are entitled to the source code.
For a web app — including APIs, SaaS dashboards, and any backend service with external users — AGPL means: if you use even one AGPL-licensed npm package, you must make your entire application's source code available to users under the AGPL license.
npm install-ing AI packages without reading their licenses is exactly how AGPL exposure enters a commercial project without notice.
AGPL also affects companies beyond startups. During M&A due diligence, AGPL in a target company's dependency tree is a common deal complication — buyers must either obtain a commercial license from the package author (if one is available) or remove the dependency before closing.
How to check all your npm package licenses
Three methods, graduated by coverage:
-
Quick sweep of direct dependencies — paste into DepCheck
Paste your
package.jsoninto DepCheck. Any copyleft-licensed package in your direct dependencies is flagged with severity and license name. No install required — runs in your browser, only package names and versions are looked up. -
Check a single package
For a quick spot-check on a specific dependency before installing:
# Show the license field from the registry npm info package-name license # For more detail: download the tarball and read the LICENSE file npm pack package-name tar -tzf package-name-1.0.0.tgz | grep -i licenseNote: the
licensefield inpackage.jsonis self-reported by the author. It can be wrong, outdated, or missing. Always confirm against the LICENSE file in the tarball for any high-stakes decision. -
Full transitive audit with license-checker
Direct dependencies are just the start. Every transitive dependency (a dependency of a dependency) carries its own license, and those obligations apply to you too. Use
license-checkerto walk your entirenode_modulestree:# Install once npm install -g license-checker # List all licenses (production deps only) license-checker --production # JSON output license-checker --production --json > licenses.json # Fail if any package falls outside your approved list license-checker --production \ --onlyAllow 'MIT;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC;CC0-1.0;Unlicense'Run this after every
npm installor dependency update. Add it as a step in your CI pipeline so a new transitive dependency with a risky license fails the build before it reaches production.
Transitive dependencies: the hidden problem
Your package.json might contain only MIT-licensed direct dependencies. But each of those packages has its own dependencies. A single AGPL package three levels deep in your dependency tree carries the same obligations as one you installed directly — you are running the code regardless of where npm install found it.
A real example of how this happens: a popular utility package (MIT) adds a new optional feature in a minor release. The feature depends on a visualization library (AGPL). Your lockfile updates on your next npm install, and a new AGPL package is now part of your production bundle without a single change to your own package.json.
package-lock.json and run license-checker --production in CI on every pull request. A new dependency in the lockfile without a passing license check is a build failure — catching this at PR time is far cheaper than during a compliance review.
What to do when you find a risky license
You have four options, roughly in order of preference:
-
Find a permissively-licensed alternative
Search npmjs.com for packages that solve the same problem. Many popular AGPL or GPL packages have MIT-licensed alternatives with comparable APIs — the ecosystem is large. Check weekly download counts and open issue velocity to assess maintenance health before switching.
-
Buy a commercial license
Many packages that use AGPL (or SSPL) for their open-source release also offer a commercial license that removes the copyleft obligation. This is the dual-licensing model — common in infrastructure software and increasingly in AI tooling. Contact the package author or check their website for commercial licensing options.
-
Isolate via a service boundary
If you run the AGPL code as a completely separate microservice — a standalone process with its own deployment, communicating only through a well-defined API — you may be able to contain the copyleft to that service's code alone, rather than your entire application. This is architecturally complex and legally uncertain; treat it as a last resort and get legal advice before relying on it.
-
Open-source under the copyleft license
If the package is genuinely the right tool and no commercial license exists, you can release your application under AGPL (or the relevant copyleft license). For internal tools, open-source developer tooling, or projects where the code is not a competitive secret, this is sometimes the cleanest path.
For packages with no license field at all: contact the author and ask them to add a license (most will add MIT if asked). If the package is a transitive dependency, open an issue on the upstream package that pulled it in, or switch to an alternative that uses a fully-licensed dependency chain.
Scan your package.json for license risk →
Frequently asked questions
Does npm audit check for license issues?
No. npm audit only checks your dependency tree against the npm advisory database for published security vulnerabilities (CVEs). It has no knowledge of license types. A package carrying AGPL-3.0 or GPL-2.0 will pass npm audit with no warnings, regardless of whether those licenses are compatible with your project's commercial model. See the full pre-deploy audit guide for everything else npm audit misses.
What is the difference between AGPL and GPL for a web application?
GPL's copyleft is triggered by distribution — physically shipping software to users. Running a GPL web app on your server for users to access via a browser is generally not considered distribution, so the copyleft does not activate for a purely server-side application. AGPL closes this gap: it adds a “network use” clause that triggers copyleft when you run the software to provide a service over a network, even without distributing binaries. For virtually any web app, AGPL means you must release your entire application source code under AGPL if you use even one AGPL-licensed dependency.
Does bundling an LGPL package with webpack or Vite trigger copyleft?
This is legally unsettled. The LGPL was designed to allow dynamic linking against a library without triggering copyleft. JavaScript bundlers (webpack, Rollup, Vite, esbuild) typically inline the library's code into your output bundle — a form of static linking. Many legal teams treat bundled LGPL as triggering copyleft obligations on the library's code (requiring you to open-source modifications to the LGPL library, but not your entire application). Others disagree. If in doubt, prefer a permissively-licensed alternative or get legal advice.
Can I use an AGPL package for an internal tool that is not public-facing?
Possibly. AGPL's network-use clause triggers when you run the software to provide a service to users other than yourself. A tool used only by employees of your own organization on your internal network is generally not considered providing a service to external users. However, if external contractors access it, if it's sold as SaaS, or if the boundary is ambiguous, AGPL likely applies. Get legal advice before relying on the “internal only” exception for high-stakes cases.
What does “SEE LICENSE IN LICENSE.md” mean in package.json?
It means the license is in a file inside the package tarball rather than expressed as an SPDX identifier string. This appears when a project uses a custom license, a dual license, or a license with conditions that don't fit a standard SPDX tag. You need to read that file before assuming the package is permissive. Download the package with npm pack package-name, extract the tarball, and open the LICENSE file to read the actual terms.
Is a package with no license field in package.json safe to use?
No — not without confirming with the author. A missing license field legally means “all rights reserved.” You have no permission to use, copy, modify, or distribute the package. In practice, many small packages omit the license field accidentally and the author intended permissive use, but you cannot rely on assumed intent. For any production dependency with no license, contact the author and ask them to add one, or find a licensed alternative.
How do I check the licenses of all transitive dependencies, not just direct ones?
Run npx license-checker --production in your project root after installing dependencies. This walks the full node_modules tree and prints every package name, version, and license — including transitive dependencies. Use --onlyAllow 'MIT;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC' to fail the command if any package falls outside your approved list, making it suitable as a CI gate.
Also in the Copper Bay Labs ship-safety suite
License risk is one layer of your pre-ship checklist. These free tools cover the rest:
Paste code or a config file and see exposed API keys and secrets flagged before they reach the repo.
Post-deploy ExposureCheckScan your live URL for exposed .env files, .git directories, source maps, and bundled secrets.
Check your security headers — CSP, HSTS, X-Frame-Options — so your site is not an exfiltration vector.
ADA / WCAG risk ShipSafeScan your site for accessibility failures that create ADA lawsuit risk before you launch.