# Black: Python Code Formatter

Black is an opinionated Python code formatter that rewrites source files to conform to a strict subset of [PEP 8](https://pydevtools.com/handbook/explanation/what-is-pep-8.md). It exposes few configuration options by design, so teams converge on one canonical style instead of debating formatting choices.

## When to use Black

Black fits codebases that already run it in CI or [pre-commit hooks](https://pydevtools.com/handbook/how-to/how-to-set-up-pre-commit-hooks-for-a-python-project.md) and have built workflows around its stable output. Its formatting has been the de facto Python standard since 2018, and many editor plugins, linter configs, and CI pipelines assume Black-compatible style.

For new projects, the [Ruff](https://pydevtools.com/handbook/reference/ruff.md) formatter produces nearly identical output, runs 10-100x faster, and bundles linting and import sorting in the same binary. To switch an existing project, see [How to migrate from Black to the Ruff formatter](https://pydevtools.com/handbook/how-to/how-to-migrate-from-black-to-ruff-formatter.md). To consolidate the wider lint stack at the same time, see [How to replace Black, isort, flake8, and pyupgrade with Ruff](https://pydevtools.com/handbook/how-to/how-to-replace-black-isort-flake8-pyupgrade-with-ruff.md).

## Key Features

### Formatting style

Black defaults to 88-character lines, four-space indentation, and double quotes. It adds trailing commas in multi-line constructs, normalizes string prefixes, and collapses or expands expressions to fit the line-length target. The output is deterministic: the same input always produces the same output regardless of the original formatting.

Black follows a yearly stable style cadence. Code formatted in a given calendar year stays unchanged across all releases from that year. Style changes accumulate behind `--preview` and graduate to the next year's stable style (the 2025 stable style shipped in 25.12.0, the 2026 stable style in 26.1.0). A separate `--unstable` flag exposes experimental changes that may not graduate.

### Configuration

Black reads the `[tool.black]` table in [pyproject.toml](https://pydevtools.com/handbook/reference/pyproject.toml.md). The available options are deliberately limited: `line-length`, `target-version`, `skip-string-normalization`, `skip-magic-trailing-comma`, file/directory exclusion patterns, `--preview` for changes targeting next year's stable style, and `--unstable` for experimental changes that may not graduate. This scarcity of knobs is the tool's central design choice.

### Integration

Black ships [pre-commit hooks](https://pydevtools.com/handbook/how-to/how-to-set-up-pre-commit-hooks-for-a-python-project.md), editor plugins (VS Code, PyCharm, Vim/Neovim), and a `--check` mode for CI that exits non-zero when files need reformatting. It can also format Jupyter notebooks and exposes a Python API for programmatic use.

## Pros

- Deterministic output eliminates formatting debates across teams
- Near-zero configuration required for most projects
- Yearly stable style guarantee: code formatted in a given calendar year stays unchanged across all releases from that year
- Broad ecosystem support: most Python linters and editors understand Black-compatible formatting

## Cons

- Does not lint, sort imports, or fix code issues (requires pairing with [flake8](https://pydevtools.com/handbook/reference/flake8.md) or isort for a complete code-quality pipeline)
- 10-100x slower than [Ruff](https://pydevtools.com/handbook/reference/ruff.md)'s formatter on large codebases
- The few style choices it makes (double quotes, 88-char lines) cannot be overridden without `skip-string-normalization`, and some choices have no override at all

## Learn More

- [How to migrate from Black to the Ruff formatter](https://pydevtools.com/handbook/how-to/how-to-migrate-from-black-to-ruff-formatter.md)
- [How to replace Black, isort, flake8, and pyupgrade with Ruff](https://pydevtools.com/handbook/how-to/how-to-replace-black-isort-flake8-pyupgrade-with-ruff.md)
- [Set up Ruff for formatting and checking your code](https://pydevtools.com/handbook/tutorial/set-up-ruff-for-formatting-and-checking-your-code.md) (Tutorial)
- [What is PEP 8?](https://pydevtools.com/handbook/explanation/what-is-pep-8.md)
- [Black documentation](https://black.readthedocs.io/)
- [Black on GitHub](https://github.com/psf/black)
- [The Black code style](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html)
