Skip to content

sort-collections

💼 This rule is enabled in the following configs: ✅ recommended, 📦 recommended-publishable.

🔧 This rule is automatically fixable by the --fix CLI option.

This rule enforces that specified collections (e.g. dependencies, scripts, etc.) are sorted in a consistent order.

When npm changes package dependencies through npm install, it sorts (lexicographically) all dependencies in the package.json file. However, developers will manually update package.json and unintentionally leave dependencies out of order. Doing so leads to “noise” in commits when a later change re-sorts the packages.

For most collections (dependencies, peerDependencies, etc.) this rule enforces a simple ascending lexicographical ordering (based on raw string keys).

scripts is an exception: it uses a lifecycle-aware ordering, which groups pre<name> / <name> / post<name> together (even if the middle one is missing). See Scripts Lifecycle Ordering for more details and examples.

This rule therefore aims to keep the configured collections sorted deterministically and to colocate lifecycle hook scripts for readability.

{
"scripts": {
"lint": "eslint .",
"test": "jest",
"start": "node server.js"
}
}
{
"devDependencies": {
"eslint": "^5.8.0",
"lodash.debounce": "4.17.11",
"lodash": "^4.17.11",
"mocha": "^5.2.0",
"nyc": "^13.1.0",
"prettier": "^1.14.3"
}
}

Summary:

  • Lifecycle scripts form a group: pre<name><name>post<name>.
  • The group is positioned where <name> would appear in lexicographical order, even if <name> itself is missing.
  • Groups with different base names (build, install, test, …) are ordered relative to each other by their base name.
  • All other script names (including namespaced ones like lint:fix, watch:dist) then follow the sort-package-json ordering after lifecycle grouping.

This matches the behavior of prettier-plugin-packagejson.

Missing main script (install); group still kept together:

{
"scripts": {
"preinstall": "echo pre",
"postinstall": "echo post",
"prepare": "echo prepare"
}
}

Incorrect vs. correct ordering of a complete lifecycle group:

{
"scripts": {
"build": "echo build",
"postbuild": "echo post",
"prebuild": "echo pre"
}
}
Name Description Type Required
key The collection property to sort. String Yes
order The order to sort the collection by. Keys not listed are appended in lexicographical order. String[] Yes

Pass an array of package properties to require sorting on those collections. To specify a nested property, use dot notation. All of their values must be objects.

Each entry is either:

  • A string: the collection to sort the default way (lexicographically, or lifecycle-aware for scripts)
  • An object ({ key: string; order: string[] }): sort the collection named by key using the given order; keys not listed in order are appended afterwards, sorted lexicographically

Example of only sorting devDependencies and pnpm.patchedDependencies:

{
"package-json/sort-collections": [
"error",
["devDependencies", "pnpm.patchedDependencies"]
]
}

Example of enforcing a custom order for nx while still sorting dependencies the default way:

{
"package-json/sort-collections": [
"error",
["dependencies", { "key": "nx", "order": ["npmScope", "affected"] }]
]
}

Default:

[
"config",
"dependencies",
"devDependencies",
"exports",
"optionalDependencies",
"overrides",
"peerDependencies",
"peerDependenciesMeta",
"scripts"
]
  • order-properties - Enforces that top-level properties declared in a standard order.