Skip to main content

toml-tidy

Abstract TOML sorting transformation

CI PyPI version Supported Python versions MIT license pre-commit integration Trunk integration

Sort TOML keys while preserving table hierarchy and source formatting where tomlkit supports it.

Install

Install from PyPI:

pip install toml-tidy

Or as a standalone tool with uv:

uv tool install toml-tidy

Or run it once without installing:

uvx toml-tidy pyproject.toml

For development from a local checkout, use uv tool install ..

Usage

toml-tidy pyproject.toml
toml-tidy pyproject.toml --check
toml-tidy pyproject.toml --in-place --order natural
toml-tidy config/*.toml --in-place --scope tables

The command accepts one or more file paths and processes each one, so it works directly as a pre-commit or trunk formatter target.

Without --in-place, sorted TOML is written to standard output; this mode takes exactly one path so separate documents never get concatenated.

--check writes nothing and exits with status 1 when any file requires sorting.

--in-place rewrites each file only when sorting changes it.

With multiple paths the worst exit code wins: 2 for any error, else 1 for any check difference, else 0; an error in one file does not stop the remaining files.

--scope limits what gets sorted: all (default) sorts everything, tables sorts only sibling table declarations, and keys sorts only direct key-value entries.

--blank-lines additionally normalizes blank lines to exactly one before every table header and none anywhere else; --no-blank-lines (the default) leaves every blank line where it was.

Configuration

Defaults can be set in the nearest pyproject.toml found walking up from each target file, under [tool.toml-tidy]. CLI flags always override the configuration.

[tool.toml-tidy]
order = "natural"   # or "alpha"
scope = "all"       # "tables" | "keys"
first = ["project", "build-system"]
blank-lines = false # true normalizes blank lines

first pins top-level entries by name, in the listed order, ahead of their sorted siblings; it never applies inside nested tables, and it has no CLI flag.

Unknown keys in [tool.toml-tidy] are rejected so configuration typos cannot silently fall back to defaults.

pre-commit

repos:
  - repo: https://github.com/AndrewDongminYoo/toml-tidy
    rev: v0.5.0 # pin the latest release; the hook ships from v0.2.0 onward
    hooks:
      - id: toml-tidy

The hook runs toml-tidy --in-place, and args are appended to it, so flags are set per repository without losing in-place rewriting:

hooks:
  - id: toml-tidy
    args: [--blank-lines, --order, alpha]
    exclude: ^uv\.lock$ # lockfiles are TOML too

Trunk

toml-tidy is available as an opt-in formatter through Trunk.

See the official Trunk plugin definition for setup and runtime requirements.

Ordering

natural is the default and compares digit runs numerically, so item2 precedes item10.

alpha uses case-insensitive lexical order.

Both modes compare TOML's parsed logical key, not source quoting.

Dotted keys such as b.a = 2 sort with their sibling direct keys by their parsed dotted path, segment by segment, so a precedes b.a, which precedes b.z.

For example, [plugins.omo] precedes [plugins."omo-kit"], while the quoted spelling remains unchanged in output.

Preservation

Direct keys and sibling explicit table declarations are sorted recursively within their parent table.

Array-of-tables declarations such as [[items]] sort by name among their sibling tables, while the element order inside each array of tables remains unchanged.

Parent-child hierarchy remains unchanged.

Standalone comments move with the following key or table declaration.

Whitespace between entries remains after the preceding entry, and trailing whitespace remains at its table boundary, unless --blank-lines is enabled.

Inline comments and key quoting remain attached to their parsed tomlkit items.

Every non-empty single-line array uses one space after [ and before ]. Empty and multi-line arrays keep their source layout.

Keys inside inline tables are not reordered.

Blank lines

--blank-lines (config: blank-lines = true) is off by default and runs after sorting. It rewrites blank lines only, never comments or values:

  • Exactly one blank line precedes every table and array-of-tables header, above the comment run attached to that header rather than between the comment and the header.
  • No blank lines remain between key-value entries, inside a comment run, or at the end of the file.
  • The document's first rendered line never gains a blank line above it.
  • Blank lines inside multi-line string values belong to the value, not to the layout, and are untouched.

Given this input:

a = 1

b = 2
[x]
p = 1


[y]
q = 1

toml-tidy --blank-lines produces:

a = 1
b = 2

[x]
p = 1

[y]
q = 1

The result is stable, so --check reports a file once and reports it clean after --in-place fixes it.

Development

Run the same quality gates enforced by CI before committing:

uv run pytest
uv run ruff check src tests
uv run ruff format --check src tests
uv run basedpyright

CI runs the test suite on every supported Python version and against the lower and upper tested tomlkit patch releases because the sorter intentionally isolates a dependency on tomlkit's private container representation.

Releasing

A release is prepared on a release/vX.Y.Z branch: bump project.version, run uv lock, date the CHANGELOG section and add its compare link, and update the pre-commit rev above.

Merge that pull request first, then tag the merge commit and push the tag. Pushing the tag runs the tests, publishes to PyPI, and creates the GitHub Release from the tagged CHANGELOG section. A tag on any commit main has never pointed at is refused before anything is published — tagging a branch tip puts the artifact on PyPI before that branch's own review has landed on it, and the commit that was merged does not carry what the review added.

Metadata

Release files for toml-tidy 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for toml-tidy 0.5.0
File Size Uploaded
toml_tidy-0.5.0.tar.gz 17.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for toml-tidy 0.5.0
File Interpreter ABI Platform
toml_tidy-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 36.7 kB

Release files / toml_tidy-0.5.0.tar.gz

Download URL toml_tidy-0.5.0.tar.gz
Size 17.8 kB
Tags Source
SHA-256 checksum
How to use checksums
f56e6a7d03b9f2a1d76631e62c4f52840622c53d92cb5a30eb1a0091642fc7f7
BLAKE2b-256 checksum
How to use checksums
ab1e9e1d3257494614cc360bf566791047301d35f0af0eca6e6734758b9997d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / toml_tidy-0.5.0-py3-none-any.whl

Download URL toml_tidy-0.5.0-py3-none-any.whl
Size 18.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
770b4d263fa9cec82895e1fdf36cfe5cee3135ffc700782ff36b648fbe5b67b2
BLAKE2b-256 checksum
How to use checksums
f051a0949e64c45b4c2baec5ba9a6ebaaf3882fb5cff60b97cf6989e21b86b99
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.6.0

2 release files

This release

0.5.0 This release

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page