How to set up prek hooks for a Python project
prek is a fast drop-in replacement for pre-commit that runs hooks faster, uses less disk space, and ships as a single binary with no Python dependency. It reads the same .pre-commit-config.yaml files, so the configuration in this guide also works with pre-commit. See the pre-commit version of this guide for the original tool.
Installing prek
Install prek as a CLI tool with uv:
$ uv tool install prek
Then install the Git hook in your project:
$ prek install
This places a hook script in .git/hooks/pre-commit that runs automatically on git commit.
Migrating from pre-commit
If the project already uses pre-commit, swap it out without changing any configuration:
$ pre-commit uninstall && prek install
The existing .pre-commit-config.yaml works as-is.
Creating the configuration file
prek reads the same .pre-commit-config.yaml format as pre-commit. Here is a starting configuration that uses Ruff for linting and formatting:
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.13
hooks:
- id: ruff-check
args: [--fix]
- id: ruff-formatThe ruff-check hook runs the linter with auto-fix enabled. The ruff-format hook runs the formatter. They execute in order, so linting fixes are applied before formatting.
Tip
Run prek auto-update to update all hook versions to their latest releases.
Adding more hooks
Trailing whitespace and file endings
The pre-commit-hooks repository provides several lightweight checks:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-filesUsing prek’s built-in hooks
prek ships with Rust-native implementations of common hooks that require no external toolchain. Use repo: builtin to access them:
repos:
- repo: builtin
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yamlBuilt-in hooks run faster than their Python equivalents because they skip virtual environment setup entirely.
Type checking with mypy
To run mypy as a hook:
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v2.1.0
hooks:
- id: mypy
additional_dependencies: []Note
mypy 2.0 changed several defaults that may surface new errors in code that passed under 1.x. See the mypy reference page for details. mypy 2.0 also requires Python 3.10 or newer as both a runtime and a target.
Add any type stub packages your project needs to additional_dependencies. For example, if your project uses requests:
additional_dependencies: [types-requests]A complete configuration
Combining built-in hooks with Ruff:
repos:
- repo: builtin
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.13
hooks:
- id: ruff-check
args: [--fix]
- id: ruff-formatRunning hooks manually
To run all hooks against every file in the repository:
$ prek run --all-files
To run a specific hook:
$ prek run ruff-check --all-files
To list all configured hooks:
$ prek list
Skipping hooks temporarily
To bypass hooks for a single commit:
$ git commit --no-verify -m "WIP: work in progress"
Use this sparingly. AI coding agents reach for --no-verify more readily than humans do; see how to stop AI agents from bypassing pre-commit hooks for the defensive setup.
Using prek in CI
Run hooks in CI to catch anything contributors skip locally. In a GitHub Actions workflow:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v7
- run: uv tool install prek
- run: prek run --all-filesTroubleshooting
If hooks are not running on commit, verify the hook is installed:
$ prek install
To clear cached hook environments (useful after updating Python or hook versions):
$ prek clean