Use Black or Ruff for Python files, then use blacken-docs for code blocks in your docs. That combo gives you clean code, clean examples, and fewer silly review comments about spaces.
TLDR: Black is the classic “just format it” tool. Ruff is faster and can lint, sort imports, and format code in one setup. blacken-docs formats Python snippets inside Markdown and reStructuredText files, like README examples. On one 8-person team, this kind of setup cut style comments in pull requests by about 35% in two weeks.
Why formatting tools matter
Python is easy to read. Until it is not.
One developer uses 88 characters per line. Another uses 120. Someone lines up dictionaries by hand. Someone else breaks every function call into five lines. Then a tiny change creates a huge diff. It drives me crazy when a one-line fix turns into 40 changed lines because a formatter was missing.
Formatters stop that mess.
They make code boring. Boring is good. Boring code is easy to review. Easy to review means bugs are easier to spot.
But there is one sneaky problem. Your docs have code too.
That is where blacken-docs comes in.

What is blacken-docs?
blacken-docs formats Python code blocks inside documentation files.
It works with files like:
- Markdown files, such as
README.md - reStructuredText files, such as
docs/index.rst - Python examples inside tutorials
- Code snippets in API guides
Think of it as a neat little helper for docs. Black formats your Python files. blacken-docs formats the Python hiding inside your docs.
Example before:
```python
def add( a,b ):
return(a+b)
```Example after:
```python
def add(a, b):
return a + b
```Small change. Big relief.
Black vs Ruff: the quick answer
Black is the safe, famous formatter. It has been used for years. It has one strong opinion. You accept it, and it formats your code.
Ruff is a newer tool written in Rust. It is very fast. It started as a linter, but now it can also format code. It can replace several tools in many projects.
Here is the simple split:
- Use Black if you want the trusted default formatter.
- Use Ruff if you want linting, formatting, and import sorting in one fast tool.
- Use blacken-docs if your docs include Python examples.
The catch is that Ruff and Black are very close, but not always identical in every edge case. For most teams, that is fine. For strict projects, pick one formatter and stick to it.
Black: the strict friend
Black calls itself “the uncompromising code formatter.” That is accurate.
You do not spend hours tuning it. You do not argue about many style rules. You run it, and it changes the code.
What Black does well:
- Formats Python code with very little setup
- Reduces style debates
- Works well with editors and CI
- Uses a common line length of
88
What may annoy you:
- It may reformat code in a way you did not expect.
- It does not sort imports.
- It does not lint your code.
So Black is great. But it is not a full code quality kit. You often pair it with isort and Flake8 or another linter.
Ruff: the speedy toolbox
Ruff is fast. Really fast.
On many projects, Ruff checks files in less than a second. A setup that took 8 seconds with older lint tools may take under 1 second with Ruff. That matters when you run checks all day.
Ruff can do many jobs:
- Lint Python code
- Format Python code
- Sort imports
- Fix many issues automatically
- Replace parts of Flake8, isort, pyupgrade, and more
That sounds lovely because it is. Fewer tools mean fewer config files. Fewer config files mean fewer “why is CI angry again?” moments.
What Ruff does well:
- Runs very fast
- Combines many checks
- Has strong editor support
- Can auto-fix lots of small issues
What may annoy you:
- It has many rules, so setup can feel noisy at first.
- Some teams still prefer Black for formatting.
- You may need to tune rules for older codebases.

Where blacken-docs fits
Use blacken-docs after you pick Black or Ruff for normal code.
Docs often get ignored. Then examples rot. A function signature changes. A snippet gets copied from an old test. The formatting looks weird. New users copy it, run it, and get mad.
blacken-docs helps keep examples sharp.
It finds Python code blocks and formats them. This is handy for:
- Open source projects with large README files
- Internal docs for developer teams
- Training guides
- API documentation
- Blog posts with Python snippets
If your docs are part of your product, this matters. Bad examples make good code look sloppy.
Other Python formatting tools
Black and Ruff get most of the attention now. Still, other tools exist.
isort
isort sorts imports. It groups standard library imports, third-party imports, and local imports.
Example:
import requests
import os
from myapp.utils import clean
import sysBecomes:
import os
import sys
import requests
from myapp.utils import cleanRuff can now handle import sorting too. So some teams remove isort. Others keep it because it works and they trust it.
autopep8
autopep8 fixes style issues based on PEP 8. It is less forceful than Black.
This can be good for older projects. It can also be less consistent. If you want one clear style, Black or Ruff is usually easier.
YAPF
YAPF is Google’s formatter. It allows more style choices.
That sounds nice. Then you realize people can argue about those choices. Honestly, that can waste more time than it saves.
docformatter
docformatter formats docstrings. It cleans up text inside triple quotes.
It is useful when your project has lots of function docs. It is not a replacement for Black, Ruff, or blacken-docs.
A simple setup that works
For many projects, this setup is enough:
- Ruff for linting and import sorting
- Black or Ruff format for Python formatting
- blacken-docs for docs
- pre-commit to run checks before every commit
Do not run two Python formatters on the same files. Pick Black or Ruff format. Not both. They are close, but small differences can cause annoying file churn.
A nice rule is:
- If your team already uses Black, keep Black.
- If you are starting fresh, try Ruff format.
- If you publish docs, add blacken-docs.

How to think about team choice
Formatting is not art class. It is plumbing.
The best tool is the one your team will run every time. It should work in the editor. It should run in CI. It should run before commits. It should not need a 40-minute meeting.
For a small team, Ruff alone may be perfect. It is quick and tidy. For a large team with years of Black history, Black plus Ruff linting may be safer. For any team with docs, blacken-docs is the missing piece.
Here is a practical decision table:
- Need maximum trust? Use Black.
- Need fewer tools? Use Ruff.
- Need faster checks? Use Ruff.
- Need formatted README code? Use blacken-docs.
- Need sorted imports only? Use Ruff or isort.
Final pick
Use Ruff if you want one fast tool for most code quality tasks. Use Black if your team wants the classic formatter with a long track record. Add blacken-docs when your documentation has Python snippets.
That is the clean setup. Code looks the same. Docs look the same. Pull requests get smaller. Reviewers stop arguing about spaces. Everyone gets back to fixing real bugs.
