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

universal-license-notice

v0.1.2

Published

Universal License Notice (uln) generates third-party license notices from package manager metadata.

Readme

Universal License Notice

Universal License Notice (uln) is a CLI for discovering package manager manifests and generating third-party license notice output from package metadata.

Its goal is to provide one tool for generating license notices across multiple package managers, saving you from having to use different tools for each manager.

The first supported package manager is npm, with additional adapters planned over time.

Status

The project is currently experimental, but available on npm for early use and feedback.

  • Supported package managers:
    • npm
  • Detected by uln but not yet supported:
    • composer
    • pypi

Current scope:

  • scans project root only
  • metadata-based notice generation, no network lookups yet
  • bundles local dependency license files when available

This tool is best-effort and is not legal advice.

Install

uln requires Node.js 20 or newer.

Install from npm:

npm install -g universal-license-notice
uln --help

For local development:

npm install
npm run build
node dist/index.js --help
npm link # If you want to directly call the binary as `uln`

Commands

scan

Reports which package managers were discovered in the current project root and whether they are currently supported.

uln scan

Example output:

Project root: /path/to/project

Package manager | Support     | Manifest files
----------------+-------------+--------------------------------
composer        | unsupported | composer.json, composer.lock
npm             | supported   | package.json, package-lock.json

Notes:
- composer (info): composer manifests were found, but this adapter has not been implemented yet.

generate

Generates third-party notice output for supported package managers in the current project root.

uln generate
  • Text output defaults to THIRD_PARTY_NOTICES.txt
  • JSON output defaults to NOTICE.json
  • HTML output defaults to NOTICE.html
  • If you do not specify a format, HTML output is used by default.
  • Full dependency license text is included by default when local package license files are available.
  • Use --dont-include-license-text to disable license text bundling.

Examples:

uln generate
uln generate --format text
uln generate --output notices.txt
uln generate --format html --output third-party-notices.html
uln generate --stdout
uln generate --stdout --format json
uln generate --config uln.config.json

--stdout and --output cannot be used together.

Configuration

If uln.config.json exists in the project root, uln generate loads it automatically.

You can also point to a config file explicitly:

uln generate --config path/to/uln.config.json

Supported fields:

{
  "managers": {
    "npm": {
      "excludePackages": ["example-package", "@author/*"],
      "packageOverrides": {
        "chalk": {
          "licenseExpression": "MIT",
          "repository": "https://github.com/chalk/chalk"
        },
        "@scope/*": {
          "licenseExpression": "MIT"
        }
      }
    }
  }
}
  • managers.<manager>.excludePackages: removes named packages from generated output; * is supported, for example @ckeditor/*
  • managers.<manager>.packageOverrides.<name>.exclude: excludes a specific package
  • managers.<manager>.packageOverrides.<name>.licenseExpression: replaces detected license metadata
  • managers.<manager>.packageOverrides.<name>.homepage, repository, author: replace detected package metadata
  • exact override keys win over wildcard keys when both match the same package
  • output.html.title: overrides the default HTML page title
  • output.html.description: overrides the default HTML page description and supports inline HTML tags
  • output.html.templatePath: path to a custom EJS template file (relative to the config file location when not absolute)

Output

Text output

The text renderer includes:

  • package manager
  • package name and version
  • whether the dependency is direct
  • license expression when available
  • repository, homepage, and author when available
  • bundled license file path and license text when available
  • warnings for missing or non-normalized license metadata

JSON output

The JSON renderer returns normalized dependency records and warnings suitable for later tooling or CI integration.

When license text bundling is enabled (default), dependency records also include licenseText and licenseSourcePath when available.

HTML output

The HTML renderer outputs a clean, GitHub Pages-style notice page with collapsible dependency sections.

Both the default template and custom templates are rendered with EJS.

  • each dependency is rendered as a section labeled package@version (SPDX code)
  • expanded sections include author, homepage, repository, direct dependency status, and package manager information
  • full license text is rendered inside <pre> when available
  • description content is rendered as HTML in the default template

You can configure HTML output metadata in uln.config.json. All of these settings are optional:

{
  "output": {
    "html": {
      "title": "Third-Party Notices",
      "description": "Generated using Universal License Notice from discovered package metadata.",
      "templatePath": "templates/custom-notice.ejs"
    }
  }
}

npm support

The current npm adapter:

  • detects package.json and package-lock.json
  • prefers package-lock.json for resolved dependency metadata
  • uses package.json and lockfile metadata to identify direct dependencies
  • supports modern npm lockfiles first (lockfileVersion 2 and 3)
  • emits warnings when license metadata is missing or could not be normalized cleanly

If package.json exists without package-lock.json, generation falls back to direct dependencies with incomplete metadata and emits warnings.

License normalization

The current normalization layer handles a few common cases:

  • common variants like Apache License 2.0 -> Apache-2.0
  • array license values joined as OR
  • slash-delimited values like MIT/Apache 2.0
  • file-reference values like SEE LICENSE IN LICENSE.md, with warnings

Normalization is intentionally conservative. If a value cannot be normalized confidently, it is preserved and surfaced with a warning.

Development

Useful commands:

npm test
npm run lint
npm run build

Roadmap

Planned next steps:

  • Composer adapter
  • PyPI adapter
  • monorepo and manually provided manifest-path support
  • expand configuration support beyond excludes and per-package overrides
  • better output summaries and integration tests

License

MIT