How to set up prek hooks for a Python project
prek is a Rust-based 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.11.12
hooks:
- id: ruff
args: [--fix]
- id: ruff-formatThe ruff 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: v5.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: v1.16.0
hooks:
- id: mypy
additional_dependencies: []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.11.12
hooks:
- id: ruff
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 --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"
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@v6
- 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