Tidy JSON key order — and sort package.json the conventional way (canonical field order, sorted dependencies, untouched scripts). Zero dependencies.
Project description
keytidy
Tidy JSON key order — and sort package.json the way it's actually meant to
look. Inconsistent key order is pure diff noise: one teammate's editor writes
name first, another's tool writes it last, and every PR churns lines that
didn't really change. keytidy gives every JSON file one deterministic order.
Zero dependencies (pure standard library).
pip install keytidy
keytidy # sort ./package.json in place
keytidy --check # CI gate: exit 1 if anything isn't sorted
It's not just "sort all the keys"
Sorting package.json alphabetically would be wrong — name belongs at the
top, not wedged between module and optionalDependencies. So keytidy treats
package.json specially:
- Top-level fields follow the conventional order (
name,version,description, …,scripts,dependencies,devDependencies, …). Unknown fields (yourtool.*, custom keys) sort alphabetically after the known ones. - Dependency blocks (
dependencies,devDependencies,peerDependencies, …) are sorted A→Z — the part you actually want sorted. scriptsis left in your order, because script order is frequently meaningful (pretest→test→posttest, ordered build steps). Opt in with--sort-scriptsif you disagree.
Every other .json file just gets a clean recursive alphabetical sort, with
arrays left in their original order (an array is data, not config).
Example
// before
{ "version": "1.0.0", "scripts": { "test": "…", "build": "…" },
"name": "demo", "dependencies": { "zod": "…", "axios": "…" } }
// after → keytidy
{
"name": "demo",
"version": "1.0.0",
"scripts": { "test": "…", "build": "…" }, // order preserved
"dependencies": { "axios": "…", "zod": "…" } // sorted A→Z
}
Usage
keytidy # sort ./package.json in place
keytidy package.json tsconfig.json
keytidy *.json # your shell expands the glob
keytidy --check # don't write; exit 1 if any file isn't sorted
keytidy --stdout pkg.json # print the sorted result instead of writing
keytidy --indent 4 # force 4-space indent (default: detected, else 2)
keytidy --sort-scripts # also sort the package.json scripts block
keytidy --all-keys # ignore the conventional order, sort A→Z
You can also run it as a module: python -m keytidy.
Indentation is detected from the file and preserved, so keytidy doesn't fight your existing 2-space / 4-space / tab style. The trailing newline is kept as-is.
As a CI / pre-commit gate
# .pre-commit-config.yaml
- repo: local
hooks:
- id: keytidy
name: keytidy
entry: keytidy --check
language: system
files: package\.json$
Exit codes
| Code | Meaning |
|---|---|
0 |
sorted (write mode) or everything already sorted (--check) |
1 |
a file needs sorting (--check only) |
2 |
invalid JSON, or a file couldn't be read/written |
Notes
- It rewrites by parsing and re-serializing, so it normalizes JSON formatting.
It does not support comments or trailing commas (JSONC /
tsconfig.jsonwith comments will report invalid JSON rather than mangle them). - The sort itself is pure and deterministic, shared with the Node port — for typical config files the two produce identical output.
Also available for Node
Same behavior, same flags: npx keytidy
(source: keytidy).
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file keytidy-0.1.0.tar.gz.
File metadata
- Download URL: keytidy-0.1.0.tar.gz
- Upload date:
- Size: 9.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1700cc718285236bbcd934f8c9e222e4a9c5d641ad917c7d61b5a61b0a7462fa
|
|
| MD5 |
d5196b3db2407e84067331a71e5180c4
|
|
| BLAKE2b-256 |
04d98fc8dfb5a9ed0448e59f93e636bad1f76ae522471a82fa8ce88f46b4c86c
|
File details
Details for the file keytidy-0.1.0-py3-none-any.whl.
File metadata
- Download URL: keytidy-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
659ab9bb94cdb653ccd795a2f06c9bc2836c2f0350fc5cbeda040953d2c5f529
|
|
| MD5 |
4eecafbc60c27e7510975b3bdfcd1e68
|
|
| BLAKE2b-256 |
d4768ad9154330b82767d83c7d56daf32eb9cc44c65abf310affb7fb2bacec91
|