Ruff Config in ruff.toml
ruff.toml (or .ruff.toml) is a dedicated Ruff configuration file whose keys live at the top level, without the [tool.ruff] prefix.
When you do not want Ruff config in pyproject.toml, ruff.toml holds it. It uses the same keys minus the tool.ruff prefix and wins when both exist.
What it does
Ruff looks for ruff.toml or .ruff.toml alongside pyproject.toml. Keys that would be under [tool.ruff] go at the top level, and the lint and format sub-tables become [lint] and [format]. If both a ruff.toml and a pyproject.toml [tool.ruff] exist in the same directory, ruff.toml takes precedence.
Common usage
line-length = 100
target-version = "py311"
[lint]
select = ["E", "F", "I"]
[format]
quote-style = "single"Config and flags
| Item | What it does |
|---|---|
| ruff.toml / .ruff.toml | Standalone config, keys at top level |
| [lint] / [format] | Sub-tables (no tool.ruff prefix) |
| --config <path> | Point Ruff at a specific config file |
| --isolated | Ignore all config files entirely |
| extend = "<path>" | Inherit settings from another file |
In CI
Use --config to pin an explicit config in a workflow that might run from a different directory. --isolated is useful for a reproducible check that ignores any stray config a runner might pick up.
Common errors in CI
Writing [tool.ruff] inside ruff.toml is wrong: keys must be top-level, and the tool.ruff form is for pyproject.toml only, so the config is misread. Config that "does not apply" in CI is often a ruff.toml silently overriding pyproject.toml. "Failed to parse" with exit 2 is a TOML syntax error in the file.