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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@didrod2539/licenselint

v0.1.0

Published

Audit your dependency tree's open-source licenses locally: classify permissive/copyleft/network-copyleft/proprietary/unknown, enforce an allow/deny policy, and generate a CycloneDX SBOM + third-party notices. Deterministic CLI, no code uploaded.

Readme

⚖️ licenselint

Audit your dependencies' open-source licenses — locally, before legal does.

npm version CI node license

A deterministic CLI that scans your dependency tree, classifies every license (permissive / copyleft / network-copyleft / proprietary / unknown), enforces an allow/deny policy, and generates a CycloneDX SBOM and third-party notices — all locally. Your code never leaves your machine.


One-line summary

licenselint reads your installed node_modules, classifies each package's license, flags policy violations (GPL/AGPL, unlicensed, denied), and emits a score, SBOM, and attribution file — no SaaS, no upload, no API key.

Why this project exists

Open-source license violations are a real, expensive problem:

  • Ship a copyleft (GPL/AGPL) package in the wrong place and you can be obligated to open-source your own code — AGPL even across a network.
  • An unlicensed dependency ("UNLICENSED", no license field) means you have no legal right to use it at all.
  • The first thing an acquirer's due-diligence team asks for is a license inventory — and a surprise there can kill a deal.

Most teams have no idea what licenses live in their dependency tree, and the tools that do (FOSSA, Snyk, Black Duck) are paid SaaS that upload your manifest to their servers. licenselint does the deterministic, mechanical part — parse SPDX expressions, classify risk, enforce policy, generate SBOM/notices — entirely locally, so it drops into CI or a pre-merge gate with zero data exposure.

Key features

  • 🏷️ License classification — every dependency mapped to a risk class: public-domain, permissive, weak/strong copyleft, network-copyleft, proprietary, or unknown.
  • 🧮 Real SPDX parsing — handles (MIT OR Apache-2.0), A AND B, GPL-2.0-or-later WITH …, deprecated ids, and legacy licenses[] arrays.
  • 🚦 Policy engineallow/deny lists, fail-on-class, per-package overrides, exclude, and per-rule severities.
  • 📋 SBOM export — standards-compliant CycloneDX 1.5 JSON.
  • 📄 Third-party notices — attribution file grouped by license.
  • 📊 Score + A–F grade, JSON/Markdown reports, CI gate exit codes.
  • 🔒 100% local & deterministic — no network, no upload, same tree → same report.

Install

# run without installing
npx @didrod2539/licenselint scan

# or install
npm install -g @didrod2539/licenselint    # global CLI (provides `licenselint`)
npm install -D @didrod2539/licenselint    # project dev-dependency (for CI)

Node ≥ 18. ESM + CJS + TypeScript types.

Quick start

# from your project root (after npm install)
licenselint scan
Scanned 8 dependencies
  Permissive              4
  Copyleft                2
  Network copyleft        1
  Unknown / unlicensed    1

  ✗ [email protected] Uses denied license "AGPL-3.0-or-later"
      → Remove network-share or replace it with a differently-licensed alternative.
  ✗ [email protected] copyleft-lib is copyleft (GPL-3.0-only)
      → Copyleft can require sharing derivative source — confirm with legal.
  ⚠ [email protected] No license declared for mystery-pkg

Overall  0/100 (F)  8 deps, 5 error(s), 1 warning(s), 1 info

CLI usage

licenselint scan [dir]        # audit a project (default: current directory)
licenselint report <in.json>  # re-render a saved report (md | sbom | notices)
licenselint init              # scaffold licenselint.config.json
licenselint --help
licenselint --version

scan options:

| Option | Description | | --- | --- | | --config <file> | Path to a config file (otherwise auto-detected) | | --dev | Include devDependencies | | --json <file> | Write a JSON report | | --md <file> | Write a Markdown report | | --sbom <file> | Write a CycloneDX SBOM | | --notices <file> | Write a THIRD-PARTY-NOTICES file | | --min-score <n> | Exit non-zero if the overall score < n (CI gate) | | --fail-on-issues | Exit non-zero if there's any error-level issue | | --quiet | Hide info-level issues in the console |

Example result

Full reports for the bundled sample project are in examples/sample-report.md, examples/sample-sbom.json and examples/THIRD-PARTY-NOTICES.txt.

📸 Screenshot / demo GIF placeholder: ./docs/screenshot.png — record the terminal running npx @didrod2539/licenselint scan examples/sample-project.

Configuration

Create licenselint.config.json (or run licenselint init):

{
  "allow": ["MIT", "ISC", "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", "0BSD"],
  "deny": ["AGPL-3.0-only", "AGPL-3.0-or-later", "SSPL-1.0"],
  "failOn": ["copyleft", "network-copyleft", "proprietary"],
  "unknownSeverity": "warning",
  "includeDev": false,
  "minScore": 80,
  "exclude": ["internal-pkg"],
  "overrides": { "[email protected]": "MIT" },
  "ruleSeverity": { "deprecated-spdx": "info" }
}

| Field | Meaning | | --- | --- | | allow | If non-empty, every license must be in this list | | deny | These SPDX ids are always rejected (terminal) | | failOn | License classes that raise an error | | unknownSeverity | Severity for missing/unknown licenses | | includeDev | Include devDependencies | | exclude | Packages (name or name@version) to skip | | overrides | Force a package's license to a given SPDX id | | minScore | CI gate threshold (overridable with --min-score) | | ruleSeverity | Override severity per rule id |

Rule ids: denied-license, not-allowed-license, unknown-license, missing-license, copyleft-license, network-copyleft-license, deprecated-spdx, non-spdx-expression.

Real-world use cases

  1. Block risky licenses in CI. Add licenselint scan --fail-on-issues to your pipeline. A PR that pulls in a transitive AGPL package fails the build before it's ever shipped.
  2. Generate compliance artifacts for a release. Run licenselint scan --sbom sbom.json --notices THIRD-PARTY-NOTICES.txt to emit a CycloneDX SBOM and attribution file your legal/release process can attach.
  3. Prep for due diligence or an audit. licenselint scan --md licenses.md gives you a clean, per-class inventory of everything in your tree — what an acquirer or auditor will ask for, before they ask.

Programmatic API

import { scanAndAnalyze, toSbom, toMarkdown } from "@didrod2539/licenselint";

const report = scanAndAnalyze(process.cwd(), config);
console.log(report.summary.byClass);
await fs.writeFile("sbom.json", toSbom(report));
await fs.writeFile("licenses.md", toMarkdown(report));

Roadmap

  • Read package-lock.json / pnpm-lock.yaml / yarn.lock without a full install.
  • SPDX-3 / SPDX-tag-value SBOM output in addition to CycloneDX.
  • License compatibility analysis (can these licenses coexist in one distribution?).
  • Pull copyright lines from each package's LICENSE file into notices.
  • A GitHub Action that comments the license diff on PRs.
  • Workspaces / monorepo awareness.

FAQ

Does it upload my dependency list anywhere? No. licenselint runs entirely on your machine — no API key, no telemetry, no uploads, no network calls. That's the whole point versus hosted scanners.

Is this legal advice? No. It's a deterministic classifier and policy engine to surface license risk. Always confirm copyleft/unknown findings with qualified counsel.

How does it find licenses? It walks node_modules (including scoped and nested packages), reads each package.json license/licenses field, and parses the SPDX expression. If a field is missing it notes whether a LICENSE file exists so you can review.

What about package-lock.json only (no install)? Lockfile-only scanning is on the roadmap. Today it reads installed packages, which reflects exactly what you ship.

The score seems harsh/lenient — can I tune it? Yes. failOn, allow/deny, unknownSeverity, and ruleSeverity all change what's flagged; --min-score/--fail-on-issues decide what fails CI.

Why is an OR license classed by its lighter side? Because you may legally choose either — (GPL-3.0-only OR MIT) lets you take MIT, so it's treated as permissive. AND takes the stricter side.

Contributing

Contributions welcome! License classifications live in src/spdx-data.ts and policy rules in src/policy.ts. See CONTRIBUTING.md and the Code of Conduct.

git clone https://github.com/didrod205/licenselint.git
cd licenselint
npm install
npm test
npm run build
node dist/cli.js scan examples/sample-project

License

MIT © licenselint contributors

💖 Sponsor

licenselint is free, MIT-licensed, and built in spare time. If it saved you from a license surprise (or a failed audit), please consider supporting it:

Where your support goes: lockfile-only scanning, license-compatibility analysis, copyright extraction, SPDX SBOM output, a PR-commenting GitHub Action, and fast issue responses.