licsniff
v0.1.0
Published
Audit your dependencies' licenses offline and flag copyleft (GPL/LGPL/AGPL/MPL) risk. Scans node_modules, no account, no network. Zero dependencies.
Maintainers
Readme
licsniff
Audit your dependencies' licenses, offline. Point it at a project and get a
clean table of every installed package, its license, and a risk tier —
permissive, weak-copyleft, strong-copyleft, proprietary, or unknown —
so a stray GPL transitive dep can't sneak into your closed-source product.
No account. No network. No config. Zero dependencies.
npx licsniffPACKAGE VERSION LICENSE RISK
some-gpl-lib 2.1.0 GPL-3.0 strong-copyleft
mystery-pkg 0.0.3 (none) unknown
copyleft-utils 1.4.0 LGPL-2.1 weak-copyleft
left-pad 1.3.0 MIT permissive
fast-json 3.1.4 (MIT OR Apache-2.0) permissiveRiskiest first, so the line you need to worry about is at the top.
Why another license tool?
The popular license-checker
(~900K weekly downloads) has been unmaintained for years. The hosted
options — Snyk, FOSSA, Black Duck — all want a signup, a token, and a network
round-trip before they'll tell you something your node_modules already knows.
licsniff is the gap: it reads the package.json files already on your disk,
classifies each license locally, and exits. Nothing leaves the machine.
It also does the part those tools are vague about — tiering by actual risk.
Knowing a dep is "GPL-3.0" only helps if you know GPL is strong copyleft and
MPL is weak. licsniff bakes that in, understands SPDX expressions
((MIT OR Apache-2.0) → least-restrictive, GPL-3.0 AND MIT →
most-restrictive), and normalizes the messy variants (GPLv3, GPL-3.0+,
GPL-3.0-only, Apache License 2.0).
Install
npx licsniff # no install, run on demand
npm i -g licsniff # or install the `licsniff` command globallyThere's an identical Python build too: pipx run licsniff / pip install licsniff
(see licsniff-py) — it audits a Python
env's site-packages instead of node_modules. Both ports share the exact same
classifier, tested against the same vectors, so they tier licenses byte-for-byte
the same.
Usage
licsniff [options] # scans ./node_modules
licsniff --path <dir> [options] # scan a specific folder| Option | Description |
| --- | --- |
| --path <dir> | Directory to scan (default: ./node_modules). |
| --summary | Print counts per risk tier instead of the full table. |
| --json | Machine-readable JSON ({path, total, counts, packages[]}). |
| --fail-on <tier> | Exit 1 if any package is at or above <tier>. CI gate. |
| --no-color | Disable ANSI color. |
| -h, --help | Show help. |
| -v, --version | Print version. |
Risk tiers
| Tier | Examples | What it means |
| --- | --- | --- |
| permissive | MIT, ISC, BSD-2/3-Clause, Apache-2.0, 0BSD, Unlicense, CC0 | Use freely, just keep the notice. |
| weak-copyleft | LGPL-*, MPL-2.0, EPL-*, CDDL-* | File-level / linking obligations. |
| strong-copyleft | GPL-*, AGPL-* | Can force you to open-source your code. |
| proprietary | UNLICENSED, "SEE LICENSE IN …" | Not open source — read the terms. |
| unknown | missing / unrecognized | No idea — investigate manually. |
Examples
# counts at a glance
licsniff --summary
# CI gate: fail the build if anything copyleft-or-worse slipped in
licsniff --fail-on strong-copyleft
# pipe to jq
licsniff --json | jq '.packages[] | select(.tier=="unknown") | .name'
# audit some other tree
licsniff --path ./vendor/node_modulesDesign notes
- One pure function at the core.
classifyLicense(idOrName)→{tier, spdx}has no I/O, no clock, no globals. The CLI is a thinnode_modulesreader wrapped around it. That's what makes the Node and Python ports verifiably identical — they share one test table. - It reads all three
package.jsonlicense shapes. The current"license": "MIT"string, the deprecated"license": {"type": "MIT"}object, and the ancient"licenses": [...]array. - SPDX expressions are evaluated, not guessed.
ORpicks the least restrictive option (you get to choose),ANDpicks the most restrictive (you must satisfy all).WITHexception clauses fall back to the base license. - Fully offline, read-only. It never writes anything and never opens a socket. Safe to run anywhere, including air-gapped CI.
License
MIT
