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

codeowners-guard

v0.2.1

Published

GitHub-native CODEOWNERS syntax, coverage, and rule validation

Readme

CODEOWNERS Guard combines GitHub's own diagnostics with local repository checks. It runs as a native Node.js action, so it works on Linux, macOS, and Windows without pulling a container image.

Why Guard

  • GitHub is the syntax authority. Diagnostics come from the same CODEOWNERS API that evaluates the selected branch, tag, or commit.
  • Local checks cover the gaps. Duplicate patterns, rules that match no tracked file, and files without an effective owner are reported separately.
  • Action-first feedback. Findings become file annotations and a job summary, with counts exposed as workflow outputs.
  • No container startup. The Action runs directly on Node.js 24 on Linux, macOS, and Windows runners.
  • Useful outside Actions. The same core ships as a cross-platform CLI with deterministic text and JSON output.

Feature Comparison

The closest tools overlap, but they optimize for different workflows. This table compares documented behavior in fixed releases rather than treating every difference as an advantage.

| Capability | CODEOWNERS Guard 0.2.1 | codeowners-validator 0.7.4 | codeowners-audit 2.9.0 | | --- | --- | --- | --- | | Delivery | Native Node.js 24 Action and npm CLI | Docker Action and Go CLI | npm CLI and CI command | | Syntax approach | GitHub CODEOWNERS errors API at a selected ref | Built-in syntax checker | Local GitHub-parity checks | | Duplicate patterns | Built in (duplicates) | Built in (duppatterns) | Not documented | | Dangling or missing patterns | Built in (dangling) | Built in (files) | Opt-in (--fail-on-missing-paths) | | Shadowed rules | Built in (shadowed) | Experimental (avoid-shadowing) | Not documented | | Unowned tracked files | Built in (unowned) | Experimental (notowned) | Built in for non-interactive CI | | Separate owner and team lookup | Uses GitHub diagnostics; no extra lookup | Built in (owners) | Opt-in (--validate-github-owners) | | GitHub Actions feedback | File annotations, job summary, and outputs | Docker Action | Run the CLI in a workflow | | Interactive HTML coverage report | Not included | Not documented | Built in | | Team suggestions from Git history | Not included | Not documented | Opt-in (--suggest-teams) |

The comparison reflects the linked release documentation checked on 2026-09-04, with the shadowed-rules row checked on 2026-09-16. "Not documented" means the capability is not described there, not that it is impossible. Review each project's current documentation before choosing a tool.

Checks

| Check | What it reports | Severity | | --- | --- | --- | | syntax | Errors returned by GitHub's CODEOWNERS API for the selected ref | Error | | duplicates | A pattern that appears more than once | Warning | | dangling | A pattern that matches no tracked file | Warning | | shadowed | A rule that matches tracked files but never takes effect because later rules override all of them | Warning | | unowned | A tracked file with no effective owner, including files cleared by an ownerless rule | Warning |

Rules use GitHub's last-match-wins behavior. CODEOWNERS Guard searches the standard locations in GitHub's order: .github/CODEOWNERS, CODEOWNERS, then docs/CODEOWNERS.

When the syntax check is disabled, local checks assume the remaining CODEOWNERS lines are valid. Keep syntax enabled in the Action, or validate the committed ref with GitHub before relying on local-only coverage results.

See the check reference for exact matching, exclusion, and result-limit behavior.

GitHub Action

name: CODEOWNERS

on:
  pull_request:
  push:
    branches: [main]

permissions:
  contents: read

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
      - uses: rarepops/[email protected]
        with:
          checks: syntax,duplicates,dangling,shadowed,unowned
          exclude: |
            dist/
            coverage/

For the strongest supply-chain pinning, replace v0.2.1 with its full commit SHA. A complete least-privilege workflow is available in examples/codeowners.yml.

Released tags are exercised from the independent public integration repository.

The action adds file annotations and a job summary. Its default token is ${{ github.token }}, and the workflow only needs contents: read.

The Action takes its API endpoint from GitHub's runner environment. It does not accept an endpoint input that could redirect the automatically supplied token. GitHub Enterprise Server runners provide their own trusted GITHUB_API_URL.

GitHub App Tokens

The default ${{ github.token }} is enough to validate the repository that runs the workflow. When your organization restricts that token, or the workflow validates another repository, create a GitHub App installation token and pass it to github-token:

      - id: app-token
        uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
        with:
          app-id: ${{ vars.CODEOWNERS_APP_ID }}
          private-key: ${{ secrets.CODEOWNERS_APP_PRIVATE_KEY }}
      - uses: rarepops/[email protected]
        with:
          github-token: ${{ steps.app-token.outputs.token }}

Inputs

| Input | Default | Description | | --- | --- | --- | | github-token | ${{ github.token }} | Token used for GitHub diagnostics | | path | . | Repository path relative to GITHUB_WORKSPACE | | codeowners | auto-detect | Explicit CODEOWNERS path for local checks; with syntax, it must select GitHub's effective file | | checks | all checks | Comma-separated checks | | exclude | none | Newline-separated gitignore patterns omitted from local checks | | repository | ${{ github.repository }} | Repository in owner/name form | | ref | ${{ github.sha }} | Branch, tag, or commit used by the syntax check | | fail-on | warning | Failure threshold: warning or error | | max-annotations | 50 | Maximum workflow annotations and summary rows, up to 100 |

Annotation limits do not change validation counts or failure behavior. To run local checks on selected folders only, see exclusions.

Outputs

The action returns valid, issue-count, error-count, and warning-count.

CLI

Run the published CLI without installing it globally:

npx --yes [email protected] . --checks duplicates,dangling,shadowed,unowned

Use codeowners-guard@latest instead when you explicitly want the newest release. Pinning a version keeps local and CI runs reproducible.

Build and run the CLI locally:

npm ci
npm run build
node dist/cli.js .

Without --checks, the CLI runs duplicates, dangling, shadowed, and unowned. The syntax check is opt-in because it requires a GitHub repository and may require authentication.

Local checks require no network access:

node dist/cli.js . \
  --checks duplicates,dangling,shadowed,unowned \
  --exclude dist/ \
  --format json

GitHub's syntax check validates a committed branch, tag, or SHA:

GITHUB_TOKEN=ghp_example node dist/cli.js . \
  --checks syntax,duplicates,dangling,shadowed,unowned \
  --repository owner/repository \
  --ref main

Tokens are accepted only through GITHUB_TOKEN or GH_TOKEN; command-line token arguments are deliberately unsupported so credentials do not enter shell history or process listings.

GitHub's syntax endpoint always validates the effective CODEOWNERS file at the selected ref. When --codeowners is combined with syntax, the explicit path must resolve to the same effective file in the checkout.

Use --max-issues to retain up to 10,000 issue details in text or JSON output. The default is 1,000. Use --fail-on error to report local warnings without returning a failing exit status. Exit code 1 means validation failed, and exit code 2 means the command could not run.

See troubleshooting for authentication, ref mismatch, missing file, and exit-code guidance.

Explain Ownership

Explain which local rules match a file and which rule wins:

npx --yes [email protected] . --explain src/example.ts
npx --yes [email protected] . --explain src/example.ts --format json

This mode lists matching patterns in source order with their line numbers and owners. The last match wins, including ownerless rules that clear ownership. JSON includes matches, winner (or null), owners, and a status of owned, cleared, or unmatched.

Paths are relative to the repository and may name files that are not yet tracked or do not exist. This is a local explanation, not GitHub syntax or owner validation. It uses the effective CODEOWNERS file unless --codeowners selects another one. Validation flags such as --checks, --exclude, and --ref cannot be combined with --explain.

A completed explanation exits with 0, even when the file has no owner. Invalid arguments or inability to read CODEOWNERS exit with 2. Use the unowned check to enforce ownership in CI. Ownership explanations are available starting with version 0.1.3.

Design

GitHub remains the authority for syntax diagnostics. Local checks operate on files returned by git ls-files, use a maintained gitignore-compatible matcher with exceptions verified against GitHub's own matcher, and do not make separate user or team lookup calls. This keeps the Action small and avoids maintaining a second copy of GitHub's owner-resolution behavior.

The syntax check targets ref, while local checks target the checked-out working tree. In normal Actions usage both refer to the same commit. For uncommitted local changes, run local checks only or push the change to a ref before requesting GitHub diagnostics.

Security

  • GitHub workflow dependencies are pinned to immutable commit SHAs, and repository settings require SHA-pinned Actions.
  • API calls require HTTPS, reject redirects, time out after 15 seconds, cap responses at 1 MiB, and retry only bounded transient failures.
  • Action paths and CODEOWNERS files cannot escape the checked-out workspace through traversal or symbolic links.
  • Terminal text, workflow annotations, and HTML summaries escape control and bidirectional characters.
  • Dependency installation disables lifecycle scripts; CI checks advisories, registry signatures, and dependency diffs.
  • Tagged release artifacts include SHA-256 checksums and GitHub build-provenance attestations.
  • After publication, a read-only job compares npm and GitHub tarballs, verifies checksums and provenance against the release ref and commit, and smoke-tests the registry-installed CLI under Node.js 24.

Performance

  • Tracked paths stream from git ls-files -z, avoiding a fixed child-process output buffer.
  • GitHub diagnostics and tracked-file enumeration run concurrently.
  • Each file is normalized once and evaluated against ownership rules in one pass, while duplicate-only checks skip Git entirely.
  • Finding details are retained within configured bounds while exact counts and failure behavior cover every finding.
  • npm run bench measures a 10,000-rule duplicate workload and a 10,000-file by 100-rule ownership workload, with and without the shadowed check.

Development

Requires Node.js 24 or newer.

npm ci
npm run check
npm run bench

npm run check includes linting, strict type checking, tests with coverage thresholds, and a production build. dist/ is committed because GitHub executes JavaScript actions directly from the repository. CI rejects source changes that do not include rebuilt bundles and third-party notices.

License

CODEOWNERS Guard is source-available under the PolyForm Perimeter License 1.0.1. The license permits use, modification, and redistribution, but does not permit using the software to provide a competing product. Review the license terms before adopting or redistributing the project.

Licenses for packages embedded in the distributed bundles are reproduced in THIRD_PARTY_NOTICES.md.

Copyright (c) 2026 Rares (rarepops).