GitHub Packages · MIT · Node ≥ 18

pkg-field-gauge

Validate package.json before you publish: exports/main/types consistency, files, repository, keywords and sideEffects.

  1. 1 Point the @mrlouiswright scope at GitHub Packages in .npmrc

    @mrlouiswright:registry=https://npm.pkg.github.com
  2. 2 Install

    npm i -D @mrlouiswright/pkg-field-gauge
Installing from GitHub Packages needs a token

Published to GitHub Packages, not npmjs.com. GitHub Packages needs a GitHub token with read:packages to install, even for public packages: add //npm.pkg.github.com/:_authToken=${GITHUB_TOKEN} to .npmrc or run npm login --registry=https://npm.pkg.github.com.

~/project — zsh
$ npx pkg-field-gaugepkg-field-gauge — Broken_Pkg@1.0ESM package; exports, 1 bin(s), files: 2 entries CRITICAL package.json:2 name "Broken_Pkg" contains uppercase letters [invalid-name]         ↳ fix: Use a lowercase, URL-safe name (optionally @scope/name).HIGH     package.json:14 types target "lib/index.d.ts" is not included by "files", so it will be missing from the published package [not-in-files]         ↳ fix: Add "lib" to "files".MEDIUM   package.json:7 exports["."]: "types" is condition #3; TypeScript only sees it when it comes first [exports-condition-order]         ↳ fix: Move "types" to the top of the object.MEDIUM   package.json:7 exports["."].require → "./lib/index.js" is ESM ("type": "module") [format-mismatch]         ↳ fix: Point "require" at a .cjs build (or drop the condition if you only ship ESM).
Sample output from the pkg-field-gauge README.

Why it exists

A package can pass its tests and still ship broken. The types condition sits after import, so TypeScript never sees it. require points at an ESM file. main and “exports["."]” load different files. The .d.ts isn't covered by files. “sideEffects: false” lets bundlers drop your CSS. The repository doesn't match the git remote, so provenance publishing fails. pkg-field-gauge resolves every entry point on disk and checks each field the way Node, TypeScript, bundlers and npm read it. Every finding has a line number and a concrete fix.

CLI, library and GitHub Action. Node.js 18+, zero runtime dependencies. By Louis Wright.

Features

Entry points

main (resolved like Node: +.js, /index.js), module, browser, types/typings, every bin (plus a #! shebang check) and every exports target, including subpath patterns (./utils/*), conditions and fallback arrays.

exports rules

targets must start with ./ and stay inside the package; subpaths and conditions can't be mixed; types must come first and default last; require must not point at ESM and import must not point at CommonJS (checked against the extension and "type"); a types condition must point at a .d.ts; main/types must be reachable through exports["."]; ./package.json should be exported.

files

every entry point must be published (npm always includes package.json, README, LICENSE, main and bin), and entries that match nothing are reported.

Metadata

npm name rules, SemVer version, field types, type value, description, keywords, SPDX license, repository format and agreement with git remote origin, engines.node, homepage/bugs, deprecated fields (preferGlobal, typings, licenses…), sideEffects validity and the CSS trap. --require adds your own required fields.

Output

text, JSON, SARIF 2.1.0 and Markdown, with package.json line numbers; --fail-on; exit codes 0/1/2; allowlist entries with expiry dates.

Usage

# check ./package.json (run after your build)

 npx pkg-field-gauge

# Example

 npx pkg-field-gauge packages/core --fail-on medium

# Example

 npx pkg-field-gauge --require funding,engines.node

CI / GitHub Action

permissions:
  contents: read
  security-events: write   # only needed for the SARIF upload
jobs:
  pkg-field-gauge:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
        with: { persist-credentials: false }
      - uses: MrLouisWright/pkg-field-gauge@v1
        with:
          fail-on: high
          sarif: pkg-field-gauge.sarif
      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with: { sarif_file: pkg-field-gauge.sarif }

Options & flags

FlagDescription
Fields
--require <fields>Extra required fields (comma-separated, dotted paths ok: engines.node,funding)
Common
-c, --config <file>JSON config (default: .pkg-field-gauge.json or "pkgFieldGauge" in package.json)
-f, --format <fmt>text (default) | json | sarif | markdown
--json <file>Also write a JSON report
--sarif <file>Also write SARIF 2.1.0
--markdown <file>Also write Markdown (e.g. for a job summary)
--fail-on <sev>critical | high | medium | low | info | none (default: high)
--list-rulesPrint rules and default severities
--no-fixesHide fix suggestions in text output
--no-colorDisable colours

Full reference, config file format and API in the README.

Support this project

Support open-source security tools

I build free, open-source tools that help developers ship safer websites. Every coffee helps keep them maintained, documented and free for everyone.

Buy me a coffee (opens Stripe in a new tab)

Secure checkout by Stripe

Portrait of Louis Wright

About the author

Louis Wright

Cyber security researcher and software engineer based in the UK.

More tools by Louis Wright

58 tools

Sentinels security scanners & CI gates · 20