sort-package-json, one canonical key order for every package.json
Sort an Object or package.json based on the well-known package.json keys
At a glance
- What is it?
- sort-package-json rewrites a package.json so its keys follow the order npm documents, with a CLI that can check rather than rewrite and a JavaScript API for custom orders. It solves a small problem exactly, and its rules are deliberately opinionated.
- Who is it for?
- sort-package-json suits teams that want one deterministic order for package.json across a repository and want CI to fail when a file drifts, and it does not suit projects that need a particular tool's own formatting to win.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem is diff noise, not correctness
sort-package-json sorts an object or a package.json based on the well-known package.json keys. The premise is that npm's own documentation sets out a canonical order for the fields of a package.json, and a file that follows it produces smaller diffs, fewer merge conflicts and a familiar shape when you open it.
That is a small problem, and the project solves it without pretending to be more. The library is MIT licensed, written in JavaScript, published to npm as sort-package-json, and the current release line is v4.1.0, tagged on 2026-10-15, following v4.0.0 and v3.7.1 in June 2026. The last push to the repository was on the same day as the v4.1.0 tag.
The mechanics come from sort-object-keys, a separate package by the same author. The rules themselves are in defaultRules.md at the root of the repository, and the README says the initial order was derived from the package.json documentation with a few extras added for good measure. So the order is a reading of npm's documented layout rather than an independent standard, which is worth remembering when a key lands somewhere unexpected.
Sub-keys are sorted too, sometimes by a well-known order and sometimes alphabetically, which is how the nested objects such as dependencies and scripts come out tidy rather than merely the top level.
The CLI checks instead of rewriting, or reads from stdin
The quickest way to use it needs no install at all, npm 5.2 or newer is required:
npx sort-package-jsonRun in a project directory, it rewrites the package.json in place and tells you what it did, printing that the file is sorted, how many files were found and how many were successfully sorted. A global install is the alternative, with npm install --global sort-package-json.
Three flags carry the real weight. The --check flag, or -c, does not write anything. It lists the files that are not sorted and reports how many were already sorted, which is what you want in CI where the check fails rather than the fix. The --quiet flag, or -q, silences successful output but leaves error messages and the exit code alone, so a failing check is still visible. The --stdin flag reads from stdin and writes to stdout, which turns the tool into a filter:
cat package.json | sort-package-json --stdinThat combination is how you preview a change before making it, since the README shows the pattern of piping the result into diff against the original file. It is the same command as a pre-commit hook would run, only without the side effect, which makes review of the reordering trivial.
One subtlety in the --check output is worth noting. The counts reported are per file, so a run over five files can say that three were not sorted and two were already sorted, and the not-sorted paths are listed individually.
Many files, globs and an ignore option
The CLI accepts multiple file paths and globs, which is what makes it usable in a monorepo rather than only in a single project. The README shows both forms:
sort-package-json "my-package/package.json" "other-package/package.json"sort-package-json "package.json" "packages/*/package.json"Glob support comes from globby, so a pattern such as **/package.json walks the tree. There is also an --ignore option, used like this:
sort-package-json "package.json" "packages/*/package.json" --ignore "packages/one-package"In a repository with hundreds of packages, the ignore list becomes a maintenance item of its own, because a package that is excluded will keep drifting back to unsorted form and will show up in every check run. That is usually fine for a package that is generated by another tool, and it is annoying otherwise.
The combination worth running in CI is the check form over a glob, with quiet so the log stays clean:
sort-package-json "**/package.json" --checkThe exit code then reflects whether anything was out of order, which is the behaviour a pipeline needs.
A JavaScript API that returns a new value
The library is also usable as a module. The API is a single function:
sortPackageJson(packageJson, options?)Pass a JSON string and it returns a new sorted JSON string. Pass a JSON object and it returns a new sorted object. Nothing is mutated in place, which is what makes it safe to use on a parsed manifest in a script.
The one option is sortOrder, typed as string[] or Function, and defaulting to sortPackageJson.sortOrder. If you pass an array, the keys in that array are ordered as given. The important catch is in the notice in the README: fields not in that array are still sorted by defaultSortOrder. The array therefore overrides part of the order rather than replacing it:
const sorted = sortPackageJson(packageJsonObject, {
sortOrder: ['version'],
})
console.log(Object.keys(sorted))
// -> [ 'version', 'name', 'dependencies' ]If you pass a function instead, the keys are sorted with Array#sort and your comparator, which means alphabetical ordering by localeCompare is a one-liner. The trade-off is that a comparator gives you full control and full responsibility, including the fact that a comparator that is not a total order produces an implementation-defined result rather than an error.
Enforcing the order with husky and lint-staged
The README's automatic sorting section shows how to stop the drift at the point where it starts, in the commit hook. The setup installs husky and lint-staged as dev dependencies, points the prepare script at husky install, runs the prepare script, and adds a pre-commit hook that runs lint-staged:
npm install husky lint-staged --save-dev
npm pkg set scripts.prepare="husky install"
npm run prepare
npx husky add .husky/pre-commit "npx lint-staged"Then the package.json itself carries the mapping that tells lint-staged what to run on which files:
{
"lint-staged": {
"package.json": "sort-package-json"
}
}With that in place, a commit that touches package.json has the file sorted before it reaches the branch, so the diff you review is already in the canonical order. The same file can also carry a check for the whole repository in the lint script, which is what catches files that were never staged.
For a team, the two-layer approach is the sensible one. The hook keeps individual contributions clean, and the check on CI catches the packages that were committed before the hook existed or that arrive from a merge.
What the sorter will not do, and the tools that overlap it
The README has a section on keys it does not sort, and the answer is instructive. Send a pull request and it might be denied if the key is a specific vendor key of an unpopular project, for example a made-up vendor name. The rule of thumb given is that keys like browserify are sorted because that is a project with millions of users. The full list lives in defaultRules.md.
That is the honest boundary of the tool. It sorts the keys npm documents and the keys of projects the author considers worth accommodating, and it will not learn your private vendor keys unless somebody contributes them.
Three related tools are listed alongside it, and they differ in mechanism rather than in ambition. An ESLint rule with autofix runs as part of linting and fixes files as it goes. A Prettier plugin applies the ordering when Prettier formats the file, which ties the sort to formatting rather than to a separate step. A Visual Studio Code extension sorts from the editor. The difference in approach is where the sort is triggered, since the standalone tool can be pointed at files it was not asked to format and can report on them without changing them.
The project also lists a long set of supported libraries, from AVA, Babel, Browserify and c8 through to Prettier, remark, semantic-release, stylelint and Tap, in alphabetical order. That list is about the rule set recognising the configuration keys those tools use, which is the part that has to keep up as the ecosystem moves.
Editorial conclusion
sort-package-json suits teams that want one deterministic order for package.json across a repository and want CI to fail when a file drifts, and it does not suit projects that need a particular tool's own formatting to win. Before you adopt it, read defaultRules.md, which holds the full rule list, because the order is opinionated rather than derived from a published standard, and decide whether the existing related tools, an ESLint rule with autofix, a Prettier plugin or an editor extension, already cover the case in the way your team prefers.
Frequently asked questions
What does sort-package-json do and where are its rules?
It sorts the keys of a package.json using the well-known package.json key order, sorting sub-keys too, sometimes by a well-known order and sometimes alphabetically. The full rule list is in defaultRules.md at the root of the repository, and the initial order was derived from the npm package.json documentation.
How do I check whether package.json files are sorted without rewriting them?
Use the --check flag, or -c. It lists the files that are not sorted and reports how many were already sorted, without writing anything. Add --quiet to silence the successful output while keeping error messages and the exit code.
Can I use sort-package-json as a JavaScript library?
Yes, install it with npm install --save-dev sort-package-json and call sortPackageJson(packageJson, options?). Passing a JSON string returns a new sorted string and passing an object returns a new sorted object. The only option is sortOrder, which accepts an array of keys or a comparator function.
How do I sort every package.json in a monorepo?
The CLI accepts multiple paths and globs, for example sort-package-json "package.json" "packages/*/package.json", and there is an --ignore option to exclude a path such as packages/one-package. Glob support comes from globby.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/keithamus-sort-package-json)Was this useful?