npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@hunt3r/license-lens

v0.1.6

Published

Scan dependency licenses and fail PRs on disallowed or unknown licenses. Zero-dep CLI + GitHub Action.

Readme

License Lens

Zero‑dep CLI + GitHub Action to scan dependency licenses and fail PRs on disallowed or unknown licenses. Works with npm/pnpm/yarn (Node ≥ 18).

build release npm License: MIT Ko-fi


Table of contents


Overview

License Lens recursively scans node_modules/ (including nested deps) and reports each name@version → license. It then enforces your policy: disallow (e.g., GPL-3.0, AGPL-3.0), warn (e.g., LGPL-3.0), allowUnlicensed rules.

  • No registry calls; reads package.json fields (license, licenses) from installed modules
  • Supports npm, pnpm, yarn classic (workspaces OK)
  • Human‑readable table + JSON output
  • Simple exit codes for CI

Quick start

Local scan

# install deps so node_modules exists
npm ci   # or: pnpm i --frozen-lockfile  |  yarn install --frozen-lockfile

# run a scan
npx @hunt3r/license-lens check

Enforce policy (fail build if disallowed/unknown)

# add a policy file at the repo root
cat > license-lens.config.json <<'JSON'
{
  "disallow": ["GPL-3.0", "AGPL-3.0"],
  "warn": ["LGPL-3.0"],
  "allowUnlicensed": false
}
JSON

# run
npx @hunt3r/license-lens check

Usage

# basic
npx @hunt3r/license-lens check

# JSON output (machine-readable)
npx @hunt3r/license-lens check --format json

# treat UNKNOWN/UNLICENSED as error (default if allowUnlicensed=false)
npx @hunt3r/license-lens check --no-allow-unlicensed

# override config file entries via flags
npx @hunt3r/license-lens check --disallow GPL-3.0,AGPL-3.0 --warn LGPL-3.0

Exit codes

  • 0 – all good (no disallowed, and unknown allowed by policy)
  • 1 – violations found (disallowed or unknown when not allowed)
  • 2 – runtime errors (e.g., missing node_modules/)

Configuration

Create license-lens.config.json at the repo root (all keys optional):

{
  "disallow": ["GPL-3.0", "AGPL-3.0"],
  "warn": ["LGPL-3.0"],
  "allowUnlicensed": false,
  "ignore": ["[email protected]"]
}
  • disallow — licenses that fail the check
  • warn — licenses printed as warnings but do not fail
  • allowUnlicensed — allow packages missing a license field
  • ignore — exact name@version pairs to skip

CI (GitHub Actions)

Minimal workflow to enforce your policy on PRs:

name: license-lens CI
on: [pull_request]
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20 }
      - run: npm ci
      - run: npx @hunt3r/license-lens check

Make this check Required on your protected branches.


Notes & limitations

  • This tool reads from installed packages. Ensure CI runs npm ci/pnpm i --frozen-lockfile/yarn install --frozen-lockfile first.
  • Yarn Plug‑n‑Play (.pnp.cjs) is not supported in v0.1.0.
  • License heuristics:
    • Uses package.json.license if string or { type: "..." }
    • Falls back to licenses array if present
    • Otherwise marks as UNKNOWN

Security

No telemetry, no network calls. Scans local metadata only.


Contributing

PRs welcome! Please keep runtime dependency‑free and document any new license heuristics. See CONTRIBUTING.md.


License

MIT © License Lens contributors


Roadmap

  • [ ] Yarn PnP support
  • [ ] Optional SPDX validation and normalization
  • [ ] Output SPDX bill of materials (CycloneDX option)
  • [ ] Composite Action wrapper with comments on PRs

FAQ

Why not parse lockfiles?
Lockfiles don’t contain license fields. Reading node_modules/**/package.json is faster and avoids registry calls.

Will it follow pnpm symlinks?
Yes—the scanner recurses actual directories in node_modules, including scoped packages and nested trees.

Can I suppress a single package?
Use ignore: ["name@version"] in license-lens.config.json.