eslint-package-json

July 13, 2026 Β· View on GitHub

Powerful ESLint rules for package.json

Lint and autofix your package.json files with ESLint, powered by @eslint/json.

This plugin catches real package.json mistakes (invalid names, bad version ranges, broken exports, misplaced @types/*, redundant files entries, and more) and fixes many of them automatically.

Install

npm install --save-dev eslint eslint-package-json

Requires ESLint >=10.4, flat config, and ESM.

Usage

Add the recommended config to your eslint.config.js:

import packageJson from 'eslint-package-json';

export default [
	packageJson.configs.recommended,
];

This lints every package.json in your project. To tweak individual rules, add a config block after the preset:

import packageJson from 'eslint-package-json';

export default [
	packageJson.configs.recommended,
	{
		files: [
			'**/package.json'
		],
		rules: {
			'package-json/dependency-version-range': [
				'error',
				{
					range: 'caret'
				}
			]
		}
	}
];

If you prefer to wire it up manually instead of using a preset:

import json from '@eslint/json';
import packageJson from 'eslint-package-json';

export default [
	{
		files: [
			'**/package.json'
		],
		language: 'json/json',
		plugins: {
			json,
			'package-json': packageJson
		},
		rules: {
			'package-json/valid-fields': 'error'
		}
	}
];

Configs

  • recommended β€” Enables the rules that catch real, uncontroversial mistakes.
  • all β€” Enables every rule. Useful for discovering rules; not recommended for everyday use.

Rules

πŸ’Ό Configurations enabled in.
βœ… Set in the recommended configuration.
πŸ”§ Automatically fixable by the --fix CLI option.
πŸ’‘ Manually fixable by editor suggestions.

NameΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β DescriptionπŸ’ΌπŸ”§πŸ’‘
consistent-name-casingEnforce kebab-case for keys in scripts and bin objects.
consistent-path-prefixEnforce consistent ./ prefix on local path fields.βœ…πŸ”§
dependency-version-rangeEnforce a consistent version range style for dependencies.βœ…πŸ’‘
description-formatEnforce formatting of the description field.πŸ”§
no-absolute-pathsDisallow absolute paths in path fields.βœ…
no-backslash-pathsEnforce forward slashes in path fields.βœ…πŸ”§
no-core-module-dependenciesDisallow dependencies that shadow Node.js built-in modules.βœ…πŸ’‘
no-deprecated-fieldsDisallow fields and scripts that npm has deprecated.βœ…
no-dist-tag-dependenciesDisallow dist-tags as dependency specifiers.βœ…
no-duplicate-dependenciesDisallow a dependency listed in multiple dependency groups.βœ…πŸ”§
no-empty-fieldsDisallow empty fields.βœ…πŸ’‘
no-exact-peer-dependenciesDisallow exact versions for peer dependencies.πŸ’‘
no-exports-trailing-slashDisallow deprecated trailing-slash folder mappings in exports/imports.βœ…πŸ”§
no-git-dependenciesDisallow git URLs as dependency specifiers.
no-http-dependenciesDisallow HTTP URLs as dependency specifiers.βœ…
no-install-scriptsDisallow install lifecycle scripts.βœ…πŸ’‘
no-invalid-direct-overridesDisallow npm overrides that conflict with direct dependencies.βœ…πŸ”§
no-local-dependenciesDisallow local filesystem paths as dependency specifiers.
no-manual-maintainersDisallow a manually-set maintainers field.βœ…πŸ’‘
no-missing-filesDisallow missing files referenced by package metadata.
no-orphan-script-hooksDisallow pre/post script hooks without a corresponding script.βœ…
no-orphan-typesDisallow @types/* packages without a corresponding dependency.βœ…πŸ’‘
no-overrides-in-published-packageDisallow overrides in packages that can be published.βœ…πŸ’‘
no-package-manager-enginesDisallow package manager versions in the engines field.βœ…πŸ’‘
no-pre-release-dependenciesDisallow pre-release versions as dependency specifiers.
no-redundant-filesDisallow redundant entries in the files field.βœ…πŸ”§
no-redundant-repository-fieldsDisallow bugs/homepage values that duplicate what npm infers from repository.πŸ”§
no-restricted-dependenciesDisallow specific dependencies.
no-restricted-fieldsDisallow specific fields.πŸ’‘
no-self-dependencyDisallow a package depending on itself.βœ…πŸ’‘
no-typo-fieldsDisallow misspelled package.json field names.βœ…πŸ”§
no-wildcard-dependenciesDisallow wildcard version ranges for dependencies.βœ…
no-workspace-protocol-in-published-packageDisallow workspace: dependency specifiers in packages that can be published.βœ…
peer-dependencies-as-dev-dependenciesEnforce peer dependencies to also be listed in devDependencies at a compatible version.βœ…πŸ’‘
prefer-engines-rangePrefer open-ended >= ranges in the engines field.βœ…πŸ’‘
prefer-exportsPrefer an exports-first package interface.βœ…
prefer-files-fieldRequire a files allowlist.βœ…
prefer-https-urlsPrefer https:// URLs in metadata fields.βœ…πŸ”§
prefer-provenanceEnforce npm provenance via publishConfig.provenance.πŸ’‘
prefer-shorthandPrefer the shorthand string form of fields where possible.βœ…πŸ”§
prefer-side-effects-fieldRecommend declaring the sideEffects field for packages.βœ…πŸ’‘
prefer-type-moduleEnforce the type field to be module.βœ…πŸ’‘
require-bin-shebangRequire bin files to start with the exact #!/usr/bin/env node shebang.βœ…
require-default-conditionRequire a default entry in exports/imports conditions objects.βœ…
require-enginesRequire the engines.node field.βœ…
require-entry-pointRequire an entry point field.βœ…
require-exports-rootRequire a . root entry in the exports field.
require-fieldsRequire specific fields to be present, always or only for published packages.βœ…
require-private-when-workspacesRequire private when workspaces is set.βœ…πŸ’‘
require-types-in-exportsEnforce that types are exposed through the exports field.βœ…
restrict-fields-when-privateDisallow fields that have no effect when the package is private.πŸ’‘
sort-dependenciesEnforce alphabetical ordering of dependencies.βœ…πŸ”§
sort-filesEnforce a canonical order for entries in the files field.βœ…πŸ”§
sort-propertiesEnforce a canonical order for top-level package.json fields.βœ…πŸ”§
sort-scriptsEnforce alphabetical ordering of scripts.πŸ”§
types-in-dev-dependenciesEnforce @types/* packages to be in devDependencies.πŸ’‘
valid-fieldsEnforce valid values for package.json fields.βœ…πŸ”§πŸ’‘

FAQ

How is this different from eslint-plugin-package-json?

Both lint package.json through ESLint, and eslint-plugin-package-json is a great project. I built this because I wanted a different design:

  • Fewer, more powerful rules. Instead of dozens of near-identical rules (one per field, one per dependency group), I use a handful of rules with options. For example, one dependency-version-range rule with a dependencyTypes option replaces a whole family of no-caret-* / prefer-tilde-* rules. Less to learn, less to configure.
  • Native @eslint/json. I target ESLint's official JSON language directly, with no parser compatibility layer.
  • Autofix-first. Every rule that can safely fix or suggest a fix does.

Why not npm-package-json-lint?

It's a separate CLI with its own config format and no autofix. This plugin lives inside ESLint, so it shares your editor integration, --fix, and flat config.

How do I disable a rule for package.json?

package.json must be valid JSON, so it cannot contain comments.

Disable the rule in eslint.config.js instead:

import packageJson from 'eslint-package-json';

export default [
	packageJson.configs.recommended,
	{
		files: [
			'**/package.json',
		],
		rules: {
			'package-json/no-orphan-types': 'off',
		},
	},
];

Use a more specific files pattern when the rule should be disabled for only one package.