Skip to content
licensecompat checker

How to check the licenses in your dependency tree

Your manifest can't answer this. A package.json, requirements.txt, Cargo.toml or go.mod lists dependency names and versions — never their licenses. One file type is the exception, and for everything else the answer is a one-command SBOM.

The exception: npm lockfiles already have it

An npm package-lock.json at version 2 or 3 records a license field for nearly every entry — in one 527-package tree, 526 of them. So for a JavaScript project there is nothing to install and nothing to generate: paste the lockfile straight into the scanner.

yarn.lock and pnpm-lock.yaml record no licenses, so those projects take the SBOM route below.

One tool for every ecosystem

Syft reads npm, Python, Cargo, Go and others, and emits either format:

syft dir:. -o cyclonedx-json > sbom.json

Swap -o spdx-json if you prefer SPDX; the scanner reads both. If you would rather not add a binary, each ecosystem has its own generator below.

Per ecosystem

npm / pnpm / yarn

An npm package-lock.json (v2 or v3) already records a license for almost every entry, so you can scan it as-is. yarn.lock and pnpm-lock.yaml do not carry licenses, so use an SBOM for those.

npm sbom --sbom-format cyclonedx > sbom.json

Built into npm 9.10 and later; needs an installed tree.

Python (pip, Poetry, uv)

requirements.txt and the lockfiles pin versions but never licenses, so the license has to be read from the installed distributions.

cyclonedx-py environment -o sbom.json

From the cyclonedx-bom package; run it inside the target virtualenv.

Rust (Cargo)

Cargo.toml carries your crate's own license, and Cargo.lock carries none at all — the dependency licenses live in registry metadata.

cargo cyclonedx --format json

From the cargo-cyclonedx subcommand.

Go modules

go.mod and go.sum record module paths and hashes. Neither records a license, so the modules have to be inspected.

cyclonedx-gomod mod -json -output sbom.json

From the cyclonedx-gomod tool, run at the module root.

Tool flags drift between major versions; if a command is rejected, check its --help for the current spelling.

What the scan returns

One verdict for the whole tree, the resulting work's license, the obligations that follow from your distribution model, and — when a pair conflicts — which packages introduced each side, so you know what to replace. Licenses outside the dataset are listed separately and cap the verdict, so a tree is never reported clean on incomplete evidence.

Scan a dependency tree →

FAQ

Why can't I just upload my package.json or requirements.txt?
Because neither one contains license information. A manifest lists dependency names and version ranges; the license of each dependency lives in that package's own metadata. The only manifest-adjacent file that records licenses is an npm lockfile, which is why it can be scanned directly and the others cannot.
What is an SBOM?
A software bill of materials: a machine-readable inventory of every component in a build, including the license each one declares. CycloneDX and SPDX are the two common formats, and both record a license per component, which is exactly what a compatibility check needs.
Is one tool enough for every ecosystem?
Yes. Syft reads npm, Python, Cargo, Go and more, and writes both formats: 'syft dir:. -o cyclonedx-json' or '-o spdx-json'. The per-ecosystem tools are the alternative when you would rather not add another binary.
Does my dependency list get uploaded anywhere?
No. The scan runs entirely in your browser — the file is parsed locally and never sent to a server. The site has no backend to send it to.
What happens to licenses the checker doesn't recognise?
They are listed separately and they cap the verdict. A tree containing a license outside the dataset can never come back clean; it returns 'it depends' with the unrecognised licenses named, so you know exactly what still needs review.

Related: Dependency tree scanner · Compatibility matrix · Copyleft vs permissive