{"id":21719968,"url":"https://github.com/ext/npm-pkg-lint","last_synced_at":"2026-05-27T04:10:34.020Z","repository":{"id":37622038,"uuid":"311810889","full_name":"ext/npm-pkg-lint","owner":"ext","description":"Opinionated linter for NPM package tarball and package.json metadata.","archived":false,"fork":false,"pushed_at":"2026-03-30T00:33:08.000Z","size":8869,"stargazers_count":9,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-03-30T04:23:14.476Z","etag":null,"topics":["hacktoberfest","lint","npm"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ext.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"ext"}},"created_at":"2020-11-10T23:35:09.000Z","updated_at":"2026-03-30T00:31:59.000Z","dependencies_parsed_at":"2023-09-26T06:40:17.005Z","dependency_job_id":"5e2d51c1-e5fd-4997-836b-77c38b47f103","html_url":"https://github.com/ext/npm-pkg-lint","commit_stats":{"total_commits":712,"total_committers":4,"mean_commits":178.0,"dds":0.4480337078651685,"last_synced_commit":"721c4009e46b0c7366337f0b70526ff2e9de15c3"},"previous_names":[],"tags_count":105,"template":false,"template_full_name":null,"purl":"pkg:github/ext/npm-pkg-lint","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ext%2Fnpm-pkg-lint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ext%2Fnpm-pkg-lint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ext%2Fnpm-pkg-lint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ext%2Fnpm-pkg-lint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ext","download_url":"https://codeload.github.com/ext/npm-pkg-lint/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ext%2Fnpm-pkg-lint/sbom","scorecard":{"id":65164,"data":{"date":"2025-08-11","repo":{"name":"github.com/ext/npm-pkg-lint","commit":"04624c9ce896ff3bf68e45daf98797c6dabf1ad1"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":6.5,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/28 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":5,"reason":"dependency not pinned by hash detected -- score normalized to 5","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/ext/npm-pkg-lint/build.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/ext/npm-pkg-lint/build.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/ext/npm-pkg-lint/build.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/ext/npm-pkg-lint/lint.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/ext/npm-pkg-lint/lint.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/ext/npm-pkg-lint/lint.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/ext/npm-pkg-lint/lint.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/ext/npm-pkg-lint/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/ext/npm-pkg-lint/release.yml/master?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/release.yml:38","Info:   0 out of   8 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   4 out of   5 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Token-Permissions","score":10,"reason":"GitHub workflow tokens follow principle of least privilege","details":["Warn: jobLevel 'contents' permission set to 'write': .github/workflows/release.yml:16","Info: topLevel 'contents' permission set to 'read': .github/workflows/build.yml:6","Info: topLevel 'contents' permission set to 'read': .github/workflows/lint.yml:6","Info: topLevel 'contents' permission set to 'read': .github/workflows/release.yml:9"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENCE:0","Info: FSF or OSI recognized license: MIT License: LICENCE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":3,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'master'","Info: 'force pushes' disabled on branch 'master'","Info: 'branch protection settings apply to administrators' is required to merge on branch 'master'","Warn: branch 'master' does not require approvers","Warn: codeowners review is not required on branch 'master'","Warn: no status checks found to merge onto branch 'master'","Warn: PRs are not required to make changes on branch 'master'; or we don't have data to detect it.If you think it might be the latter, make sure to run Scorecard with a PAT or use Repo Rules (that are always public) instead of Branch Protection settings"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":10,"reason":"SAST tool is run on all commits","details":["Info: all commits (2) are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-15T02:26:32.233Z","repository_id":37622038,"created_at":"2025-08-15T02:26:32.233Z","updated_at":"2025-08-15T02:26:32.233Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31292096,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest","lint","npm"],"created_at":"2024-11-26T01:46:07.270Z","updated_at":"2026-04-01T21:14:56.532Z","avatar_url":"https://github.com/ext.png","language":"TypeScript","funding_links":["https://github.com/sponsors/ext"],"categories":[],"sub_categories":[],"readme":"# NPM Package linting\n\n[![Build](https://github.com/ext/npm-pkg-lint/workflows/Build/badge.svg)](https://github.com/ext/npm-pkg-lint/actions?query=workflow%3ABuild)\n[![Coverage Status](https://coveralls.io/repos/github/ext/npm-pkg-lint/badge.svg?branch=master)](https://coveralls.io/github/ext/npm-pkg-lint?branch=master)\n\nOpinionated linter for NPM package tarball and `package.json` metadata.\n\n\u003e npx npm-pkg-lint\n\nCore principles:\n\n- Technically valid according to specification is not always the best, a stricter subset makes tooling easier and less vague.\n- Native features are better than third-party code.\n- Fewer and smaller dependencies are better than many and large dependencies.\n\n## Usage\n\n\u003e npx npm-pkg-lint [--tarball my-pkg-1.2.3.tgz} [--pkgfile package.json]\n\n```\nusage: index.js [-h] [-v] [-t TARBALL] [-p PKGFILE] [--cache CACHE]\n                [--allow-dependency DEPENDENCY] [--allow-types-dependencies]\n                [--ignore-missing-fields]\n\nOpiniated linter for NPM package tarball and package.json metadata\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -v, --version         show program's version number and exit\n  -t TARBALL, --tarball TARBALL\n                        specify tarball location\n  -p PKGFILE, --pkgfile PKGFILE\n                        specify package.json location\n  --cache CACHE         specify cache directory\n  --allow-dependency DEPENDENCY\n                        explicitly allow given dependency (can be given\n                        multiple times or as a comma-separated list)\n  --allow-types-dependencies\n                        allow production dependencies to `@types/*`\n  --ignore-missing-fields\n                        ignore errors for missing fields (but still checks for\n                        empty and valid)\n  --ignore-node-version [MAJOR]\n                        ignore error for outdated node version (restricted to MAJOR version if given)\n```\n\nUse `--tarball` and `--pkgfile` to specify custom locations.\nDefault is to find `package.json` from current directory tree and derive tarball filename from the `name` and `version` field.\n\nIf `--tarball` is used `package.json` is extracted from the tarball.\n\nTo read from stdin use `--tarball -`.\nThis can be used to quickly examine packages from https://www.npmjs.com/:\n\n\u003e curl -s \\$(npm view lodash dist.tarball) | npx npm-pkg-lint -t -\n\n## Github Action\n\nThis tool can be used directly with Github Actions:\n\n```yaml\n- name: Checkout\n  uses: actions/checkout@v4\n- name: Setup Node.js\n  uses: actions/setup-node@v4\n- name: npm-pkg-lint\n  uses: ext/npm-pkg-lint@master\n```\n\n\u003e [!IMPORTANT]\n\u003e You need to have `npm-pkg-lint` installed as a dependency in `package.json`.\n\u003e This ensures you have control over which version of the tool is actually running.\n\n| Input\u0026nbsp;parameter | Default   | Description                                                                                |\n| -------------------- | --------- | ------------------------------------------------------------------------------------------ |\n| allow-dependencies   | `-`       | Comma-separated list of dependencies to explicitly allow even if they would yield an error |\n| build                | `\"build\"` | Build command (executed with `npm run`). Set to `false` to disable build.                  |\n| folders              | `\".\"`     | Space-separated list of folder to run in.                                                  |\n| ignore-node-version  | -         | Ignore error for outdated node version (see --ignore-node-version CLI argument)            |\n| npm-pack             | `true`    | When enabled `npm pack` is run automatically                                               |\n\n## Disallowed files\n\nDisallows certain files from being included in the package tarball.\n\n**Why?** They serve no purpose for the end user and makes the download larger and unpacking takes more time (which for a single package might be insignificant but with thousands of dependencies can cause delays)\n\n- Test coverage and reports\n- Unittests\n- Lint configs (eslint, prettier, html-validate, etc)\n- Webpack configs (webpack.config.js)\n- CI-related files (github actions, gitlab pipelines, etc)\n- Typescript configs (tsconfig)\n- Editor-related files\n\n## Missing files\n\nRequires files specified in `package.json` to be present.\n\n**Why?** These files are required for the end user to use the package.\n\nVerifies the presence of files specified in:\n\n- `exports` (wildcard patterns are ignored)\n- `main`\n- `browser`\n- `module`\n- `jsnext:main`,\n- `types`\n- `typings`\n- `bin`\n- `man`\n\n## `exports` paths\n\nRequires all values in `exports` to start with `./`.\n\n**Why?** The Node.js specification requires export paths to be relative paths starting with `./`.\nValues not starting with `./` will be treated as package names by some runtimes and bundlers, which is almost certainly not the intent.\n\n## `import` before `require` in `exports`\n\nRequires `import` and `module`, if either is present alongside `require`, to come before `require` in `exports`.\n\n**Why?** Some runtimes and bundlers evaluate conditions in order and stop at the first match.\nIf `require` is listed before `import` (or `module`), ESM-capable consumers that support both may unexpectedly pick up the CJS build.\n`module` is treated as an alias for `import` as it serves the same purpose for bundlers such as webpack.\n\n## `default` in `exports`\n\nRequires `default`, if present, to be the last condition in `exports`.\n\n**Why?** The `default` condition is a catch-all fallback.\nIf it is listed before more specific conditions (e.g. `require` or `import`) those conditions will never be reached by runtimes that support them.\n\n## TypeScript `types` in `exports`\n\nRequires `types` to be the first condition in `exports`.\n\n**Why?** For TypeScript to properly detect `types` it need to come before `require` or `import`, else it will fall back to detecting by filename.\n\n## TypeScript `types` matching `exports`\n\nRequires `types` to match `exports`.\n\n**Why?** To avoid issues with newer TS versions resolving with `exports` if present rather than the older `types` field.\n\n## TypeScript prefer `types` over `typings`\n\nRequires `types` to be used instead of `typings`.\n\n**Why?** While TypeScript allows `typings` to be used as an alias, it is better for consistency to only use one over the other.\n\n## TypeScript conflicting `types` and `typings` fields\n\nRequires only one of the two fields `types` and `typings` to be used, not both.\n\n**Why?** `typings` is an alias for `types` and if both are set it is unclear which is to be used (and could potentially be set to different values).\n\n## Protocol dependencies\n\nDisallows dependencies that resolve outside the registry across all dependency fields (`dependencies`, `devDependencies`, `peerDependencies`, `optionalDependencies`).\n\n**Why?** Protocol specifiers such as `file:`, `link:`, `github:` or `git+https:` reference local paths or remote git repositories instead of versioned registry packages.\nPublished packages should only depend on registry packages so that consumers can reliably install the same code.\n\nDisallowed protocols:\n\n- `file:` - local filesystem path\n- `link:` - symlink\n- `github:` / `gitlab:` / `bitbucket:` - platform shorthand\n- `git:` / `git+https:` / `git+http:` / `git+ssh:` / `git+file:` - arbitrary git URL\n- `http:` / `https:` - direct URL tarball\n- `user/repo` - Github shorthand (without `github:` prefix)\n- `user@host:path` - git URL (e.g. `git@github.com:user/repo.git`)\n\n## Disallowed dependencies\n\nDisallows certain packages from being included as `dependencies` (use `devDependencies` or `peerDependencies` instead).\n\n**Why?** These packages are meant to be used to build, lint or test the package and serve no purpose for the end user and will greatly increase the size of the dependency tree.\n\nExamples of disallowed packages:\n\n- `eslint` (including plugins and configurations)\n- `typescript` (precompile with declarations instead)\n- `grunt` (end user does not need to perform tasks inside your package)\n\nBy default `@types/*` is disallowed but this can be disabled with `--allow-types-dependencies`.\n\nIf needed, `--allow-dependency` can be used to ignore one or more dependencies.\n\n### ESLint\n\nIf your `package.json` contains the `\"eslint\"` keyword the ESLint packages can be included as dependencies, e.g. if you publish a sharable config including a plugin you must include `\"eslint\"` as a keyword.\n\n**OK**:\n\n```json\n{\n  \"name\": \"eslint-config-myfancyconfig\",\n  \"version\": \"1.0.0\",\n  \"keywords\": [\"eslint\"],\n  \"dependencies\": {\n    \"eslint-plugin-myfancyplugin\": \"^1.2.0\"\n  }\n}\n```\n\n**Fail**:\n\n```json\n{\n  \"name\": \"eslint-config-myfancyconfig\",\n  \"version\": \"1.0.0\",\n  \"dependencies\": {\n    \"eslint-plugin-myfancyplugin\": \"^1.2.0\"\n  }\n}\n```\n\n### Jest\n\nIf your `package.json` contains the `\"jest\"` keyword the Jest packages can be included as dependencies, e.g. if you publish a sharable config including a plugin you must include `\"jest\"` as a keyword.\n\n**OK**:\n\n```json\n{\n  \"name\": \"awesome-jest-config\",\n  \"version\": \"1.0.0\",\n  \"keywords\": [\"jest\"],\n  \"dependencies\": {\n    \"babel-jest\": \"^29.0.0\"\n  }\n}\n```\n\n**Fail**:\n\n```json\n{\n  \"name\": \"eslint-config-myfancyconfig\",\n  \"version\": \"1.0.0\",\n  \"dependencies\": {\n    \"babel-jest\": \"^29.0.0\"\n  }\n}\n```\n\n### Prettier\n\nIf your `package.json` contains the `\"prettier\"` keyword the Prettier packages can be included as dependencies, e.g. if you publish a sharable config including a plugin you must include `\"prettier\"` as a keyword.\n\n**OK**:\n\n```json\n{\n  \"name\": \"prettier-config-myfancyconfig\",\n  \"version\": \"1.0.0\",\n  \"keywords\": [\"prettier\"],\n  \"dependencies\": {\n    \"prettier-plugin-myfancyplugin\": \"^1.2.0\"\n  }\n}\n```\n\n**Fail**:\n\n```json\n{\n  \"name\": \"prettier-config-myfancyconfig\",\n  \"version\": \"1.0.0\",\n  \"dependencies\": {\n    \"prettier-plugin-myfancyplugin\": \"^1.2.0\"\n  }\n}\n```\n\n## Obsolete dependencies\n\nDisallows certain packages from being included as `dependencies`, `devDependencies` or `peerDependencies` entirely.\nThese dependencies have native replacements supported by all supported NodeJS versions.\n\n**Why?** Obsolete packages have native replacements and thus only clutter the dependency graphs thus increasing the time to install, the size on disk and produces noise with tools analyzing `package-lock.json`.\n\nExamples of obsolete packages:\n\n- `mkdirp` - `fs#mkdir` supports the `recursive` flag since NodeJS v10.\n- `stable` - `Array#sort` is stable since NodeJS v12.\n\n## Deprecated dependencies\n\nDisallows deprecated packages from being included as `dependencies`, `devDependencies` or `peerDependencies` entirely.\nThese dependences are explicitly marked as deprecated by the package author.\n\n**Why?** Deprecated packages should be removed or replaced with alternatives as they are often unmaintained and might contain security vulnerabilities.\n\nExamples of obsolete packages:\n\n- `mkdirp` - `fs#mkdir` supports the `recursive` flag since NodeJS v10.\n- `stable` - `Array#sort` is stable since NodeJS v12.\n\nIf needed, `--allow-dependency` can be used to ignore one or more dependencies.\n\n## Shebang\n\nRequire all binaries to have UNIX-style shebang at the beginning of the file.\nNormally this is `#/usr/bin/env node`.\n\n**Why?** Binaries must have a shebang at the beginning of the file to be executable for end users.\n\n## `package.json` fields\n\nVerifies the fields in `package.json` and ensures all fields are properly set.\n\n**Why?** While many fields strictly are optional they help end users find the package and source code, where and how to report bugs and how the package can be used.\n\nVerifies the following fields:\n\n- `description` - present and non-empty\n- `keywords` - present and non-empty\n- `homepage` - present, non-empty and well-formed\n- `bugs` - present, non-empty, and well-formed\n- `license` - present and non-empty\n- `author` - present and non-empty\n- `repository` - present, non-empty and well-formed\n\nIt also enforces all urls to be `https`, even the repository url.\nWhile `git` is technically valid most users cannot clone the repository anonomously.\nShortcuts are not permitted either because it saves basically nothing, makes tooling more difficult to write and wont work for smaller hosting services.\n\nWhen the `--ignore-missing-fields` option is used the fields can be omitted (but still need to be valid if present).\n\n## Unsupported node versions\n\nRequires `engines.node` to be up-to-date and only supporting LTS and active versions.\n\n**Why?** Newer versions contains more builtin functions and features replacing the need for polyfills and many one-liner packages.\n\nAs an example `mkdirp` can be replaced with `fs.mkdir(p, { recursive: true })` starting with Node 10.\n\nWhile stable Linux distributions (e.g. Debian stable) and enterprise environment might not use the most recent versions they often try to stay away from EOL versions.\nUsers stuck at older versions will not be able to update to the latest set of node packages but if you are using an environment with unsupported versions you are unlikely to want to update node packages.\nIt is also very likely that the package doesn't actually run on such old version anyway because of a missing feature or a dependency requiring a later version.\n\nThis rule can be ignored with `--ignore-node-version`.\n\n## Verify engine constraints\n\nRequires `engines.node` to be satisfied by all transitive dependencies.\n\n**Why?** It is a common error forget to verify transitive dependencies when setting constraints on node version.\n\nIf `package.json` declares constraint such as:\n\n```json\n{\n  \"dependencies\": {\n    \"my-dependency\": \"1.2.3\"\n  },\n  \"engines\": {\n    \"node\": \"\u003e= 8\"\n  }\n}\n```\n\nbut the `my-dependency` constraint requires NodeJS 12 or later this rule yields an error as NodeJS 8 will not satisfy that constraint.\n\n## `@types/node` and engine constraints\n\nRequires `engines.node` lowest major version to equal `@types/node` major version.\n\n**Why?** If you use the wrong major version of `@types/node` you might write code with is unsupported by the versions claimed to be supported by `engines.node` or you might be missing out on newer features that could be used.\n\nFinal compatibility should be tested with a version matrix but having `@types/node` at the correct version can give the developer early assistance.\n\nThe following `package.json`:\n\n```json\n{\n  \"devDependencies\": {\n    \"@types/node\": \"^14.17.16\"\n  },\n  \"engines\": {\n    \"node\": \"\u003e= 12\"\n  }\n}\n```\n\nwill yield an error becase `node` v12 is not the same as `@types/node` v14.\n\n## `@tsconfig/node*` and engine constraints\n\nRequires `engines.node` lowest major version to match the `@tsconfig/node*` base package.\n\n**Why?** If you use the wrong `@tsconfig/node*` base package you might be targeting and outputing code that will be unsupported by the versions claimed to be supported by `engines.node` or you are outputting inefficient code which isn't taking advantage of newer features that could be used.\n\nFinal compatibility should be tested with a version matrix but having `@tsconfig/node*` at the correct version can give the developer early assistance.\n\nThe following `package.json`:\n\n```json\n{\n  \"devDependencies\": {\n    \"@tsconfig/node14\": \"^14.1.2\"\n  },\n  \"engines\": {\n    \"node\": \"\u003e= 12\"\n  }\n}\n```\n\nwill yield an error becase `@tsconfig/node14` is for NodeJS v14 but the `engines.node` constraints the version to v12.\n\n## `package-lock.json` lockfile\n\nRequires `package-lock.json`, if present, to pass the following checks:\n\n- Lockfile version must be 3.\n- All packages must be resolved from `https://registry.npmjs.org/`.\n\n**Why?** Lockfile version 3 (introduced with npm v7) includes the full dependency tree in a more compact and efficient format.\nOlder lockfile versions (1 and 2) are either missing information or include redundant data that version 3 supersedes.\nUsing version 3 ensures compatibility with modern npm tooling and avoids the ambiguity of the legacy formats.\n\n**Why?** Packages resolved from private registries, git URLs, or local paths indicate non-standard dependencies that may not be reproducible in all environments.\nAll published production dependencies should be resolvable from the public npm registry to ensure consumers can reliably install the same code.\n\nTo upgrade an existing lockfile to version 3 run:\n\n```sh\nnpm install --lockfile-version 3 --package-lock-only\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fext%2Fnpm-pkg-lint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fext%2Fnpm-pkg-lint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fext%2Fnpm-pkg-lint/lists"}