Configuration Referenceยถ
This page documents the configuration keys that prek understands.
Global config fileยถ
prek reads an optional user-level global config from:
- Linux and macOS:
~/.config/prek/prek.toml(or$XDG_CONFIG_HOME/prek/prek.tomlwhenXDG_CONFIG_HOMEis set) - Windows:
%APPDATA%\prek\prek.toml
This file stores user-level prek settings and does not define project hooks.
Global auto_update.cooldown_daysยถ
Default cooldown for prek auto-update.
- Type: integer days,
0to255 - Default:
0 - CLI override:
prek auto-update --cooldown-days <DAYS>
The age is computed from the tag creation timestamp for annotated tags, or from the tagged commit timestamp for lightweight tags. A value of 0 disables the cooldown check.
Cooldowns never downgrade
If the current rev is newer than the latest cooldown-eligible tag, prek auto-update keeps the current rev instead of downgrading it.
Project configs can also set auto_update.cooldown_days. The effective precedence is:
prek auto-update --cooldown-days <DAYS>- project config
- user-level global config
- default
0
Top-level keysยถ
repos (required)ยถ
A list of hook repositories.
Each entry is one of:
- a remote repository (typically a git URL)
repo: localfor hooks defined directly in your repositoryrepo: metafor built-in meta hooksrepo: builtinforprek's built-in fast hooks
See Repo entries.
filesยถ
Global include regex applied before hook-level filtering.
- Type: regex string (default, pre-commit compatible) or a prek-only glob pattern mapping
- Default: no global include filter
This is usually used to narrow down the universe of files in large repositories.
What path is matched? (workspace + nested projects)
files (and exclude) are matched against the file path relative to the project root โ i.e. the directory containing the configuration file.
- For the root project, this is the workspace root.
- For a nested project, this is the nested project directory.
Example (workspace mode):
- Root project config:
./.pre-commit-config.yaml - Nested project config:
./nested/.pre-commit-config.yaml
For a file at nested/excluded_by_project:
- Root project sees the path as
nested/excluded_by_project - Nested project sees the path as
excluded_by_project
This matters most for anchored patterns like ^...$.
Regex matching
When files / exclude are regex strings, they are matched with search semantics (the pattern can match anywhere in the path).
Use ^ to anchor at the beginning and $ at the end.
prek uses the Rust fancy-regex engine.
Most typical patterns are portable to upstream pre-commit, but very advanced regex features may differ from Pythonโs re.
prek-only globs
In addition to regex strings, prek supports glob patterns via:
files: { glob: "..." }(single glob)files: { glob: ["...", "..."] }(glob list)
This is a prek extension. Upstream pre-commit expects regex strings here.
For more information on the glob syntax, refer to the globset documentation.
Examples:
excludeยถ
Global exclude regex applied before hook-level filtering.
- Type: regex string (default, pre-commit compatible) or a prek-only glob pattern mapping
- Default: no global exclude filter
exclude is useful for generated folders, vendored code, or build outputs.
What path is matched?
Same as files: the pattern is evaluated against the file path relative to the project root (the directory containing the config).
prek-only globs
Like files, exclude supports glob (single glob or glob list) as a prek extension.
For glob syntax details, see the globset documentation.
Examples:
Verbose regex example (useful for long allow/deny lists):
fail_fastยถ
Stop the run after the first failing hook.
- Type: boolean
- Default:
false
This is a global default; individual hooks can also set fail_fast.
default_language_versionยถ
Map a language name to the default language_version used by hooks of that language.
- Type: map
- Default: none (hooks fall back to
language_version: default)
Example:
prek treats language_version as a version request (often a semver-like selector) and may install toolchains automatically. See Difference from pre-commit.
default_stagesยถ
Default stages used when a hook does not specify its own.
- Type: list of stage names
- Default: all stages
Allowed values:
manualcommit-msgpost-checkoutpost-commitpost-mergepost-rewritepre-commitpre-merge-commitpre-pushpre-rebaseprepare-commit-msg
default_install_hook_typesยถ
Default Git shim name(s) installed by prek install when you donโt pass --hook-type.
- Type: list of
--hook-typevalues - Default:
[pre-commit]
This controls which Git shims are installed (for example pre-commit vs pre-push).
It is separate from a hookโs stages, which controls when a particular hook is eligible to run.
Allowed values:
pre-commitpre-pushcommit-msgprepare-commit-msgpost-checkoutpost-commitpost-mergepost-rewritepre-merge-commitpre-rebase
auto_update.cooldown_daysยถ
prek-only
This top-level key is a prek extension and is not recognized by upstream pre-commit.
Project default cooldown for prek auto-update.
- Type: integer days,
0to255 - Default: inherited from the user-level global config, or
0 - CLI override:
prek auto-update --cooldown-days <DAYS>
In workspace mode, this setting is scoped to the project config file that defines it. It applies only to that project and is not inherited by nested projects. Sub-projects use their own auto_update setting, then the user-level global config, then the default. If two projects use the same repo URL with different cooldown settings, prek auto-update fetches the repo once but evaluates each project with its own cooldown.
minimum_prek_versionยถ
prek-only
This key is a prek extension. Upstream pre-commit uses minimum_pre_commit_version, which prek intentionally ignores.
Require a minimum prek version for this config.
- Type: string (version)
- Default: unset
If the installed prek is older than the configured minimum, prek exits with an error.
Example:
orphanยถ
prek-only
orphan is a prek workspace-mode feature and is not recognized by upstream pre-commit.
Workspace-mode setting to isolate a nested project from parent configs.
- Type: boolean
- Default:
false
When orphan: true, files under this project directory are handled only by this projectโs config and are not โseenโ by parent projects.
Example:
See Workspace Mode - File Processing Behavior for details.
Repo entriesยถ
Each item under repos: is a mapping that always contains a repo: key.
Remote repositoryยถ
Use this for hooks distributed in a separate repository.
Required keys:
repo: repository location (commonly an https git URL)rev: version to use (tag, branch, or commit SHA)hooks: list of hook selections
Remote hook definitions live inside the hook repository itself in the
.pre-commit-hooks.yaml manifest (at the repo root). Your config only selects
hooks by id and optionally overrides options. See Authoring Hooks
if you maintain a hook repository.
repoยถ
Where to fetch hooks from.
In most configs this is a git URL.
prek also recognizes special values documented separately: local, meta, and builtin.
revยถ
The revision to use for the remote repository.
Use a tag or commit SHA for repeatable results. If you use a moving target (like a branch name), runs may change over time.
hooksยถ
The list of hooks to enable from that repository.
Each item must at least specify id.
You can also add hook-level options (filters, args, stages, etc.) to customize behavior.
Example:
Notes:
- For reproducibility, prefer immutable pins (tags or commit SHAs).
prek auto-updatecan help updaterevvalues.
repo: localยถ
Define hooks inline inside your repository.
Keys:
repo: must belocalhooks: list of local hook definitions (see Local hook definition)
Example:
repo: metaยถ
Use pre-commit-style meta hooks that validate and debug your configuration.
prek supports the following meta hook ids:
check-hooks-applycheck-useless-excludesidentity
Restrictions:
idis required.entryis not allowed.language(if set) must besystem.
You may still configure normal hook options such as files, exclude, stages, etc.
Example:
repo: builtinยถ
prek-only
repo: builtin is specific to prek and is not compatible with upstream pre-commit.
Use prekโs built-in fast hooks (offline, zero setup).
Restrictions:
idis required.entryis not allowed.language(if set) must besystem.
Example:
For the list of available built-in hooks and the โautomatic fast pathโ behavior, see Built-in Fast Hooks.
Hook entriesยถ
Hook items under repos[*].hooks have slightly different shapes depending on the repo type.
Remote hook selectionยถ
For a remote repo, the hook entry must include:
id(required): selects the hook from the repository
All other hook keys are optional overrides (for example args, files, exclude, stages, โฆ).
Advanced overrides
prek also supports overriding name, entry, and language for remote hooks.
This can be useful for experimentation, but it may reduce portability to the original pre-commit.
Local hook definitionยถ
For repo: local, the hook entry is a full definition and must include:
id(required): stable identifier used byprek run <id>and selectorsname(required): label shown in outputentry(required): command to executelanguage(required): howpreksets up and runs the hook
Builtin/meta hook selectionยถ
For repo: builtin and repo: meta, the hook entry must include id.
You can optionally provide name and normal hook options (filters, stages, etc), but not entry.
Common hook optionsยถ
These keys can appear on hooks (remote/local/builtin/meta), subject to the restrictions above.
idยถ
The stable identifier of the hook.
- For remote hooks, this must match a hook id defined by the remote repository.
- For local hooks, you choose it.
id is also used for CLI selection (for example prek run <id> and PREK_SKIP).
Hook ids containing :
If your hook id contains : (for example id: lint:ruff), prek run lint:ruff
will not select that hook. prek interprets lint:ruff as the selector
<project-path>:<hook-id>, with project lint and hook ruff.
To select the hook id lint:ruff, add a leading : and run
prek run :lint:ruff.
nameยถ
Human-friendly label shown in output.
- Required for
repo: localhooks. - Optional as an override for remote/meta/builtin hooks.
entryยถ
The command line to execute for the hook.
- Required for
repo: localhooks. - Optional override for remote hooks.
- Not allowed for
repo: metaandrepo: builtin.
If pass_filenames is true, prek appends matching filenames to this command when running.
shellยถ
prek-only
shell is a prek extension and may not be recognized by upstream pre-commit.
Run entry through a predefined shell adapter.
- Type: one of
sh,bash,pwsh,powershell,cmd - Default:
null(runentrydirectly without a shell)
When shell is omitted, prek preserves the default no-shell behavior: it parses entry into argv, invokes the command directly, and appends args and matching filenames as process arguments.
When shell is set, entry is treated as source for that shell. prek writes the source to a temporary script file, runs it with the selected shell adapter, and passes hook args followed by matching filenames as script arguments.
shell |
Adapter command | Script arguments |
|---|---|---|
bash |
bash --noprofile --norc -eo pipefail <script> |
"$@" |
sh |
sh -e <script> |
"$@" |
pwsh |
pwsh -NoProfile -NonInteractive -File <script> |
$args |
powershell |
powershell -NoProfile -NonInteractive -File <script> |
$args |
cmd |
cmd /D /E:ON /V:OFF /S /C CALL <script> |
%* |
Unsupported languages
shell is rejected for language backends that do not run entry through
the shell-aware entry resolver, and for repo: meta and repo: builtin
hooks.
| Language | Why shell is unsupported |
|---|---|
docker, docker_image |
entry participates in container image or entrypoint selection instead of direct host process execution. |
dart |
Dart package config injection requires entry to resolve to a direct dart command. |
fail |
entry is the failure message body. |
julia, rust |
entry participates in install/runtime package resolution and is split before execution. |
pygrep |
entry is the regex pattern. |
conda, coursier, perl, r |
The language backend is not implemented yet. |
languageยถ
How prek should run the hook (and whether it should create a managed environment).
- Required for
repo: localhooks. - Optional override for remote hooks.
- Not allowed (except as
system) forrepo: metaandrepo: builtin.
Common values include system, python, node, rust, golang, ruby, and docker.
See Language Support for per-language behavior, supported values, and language_version details.
Language name aliases
For compatibility with upstream pre-commit, the following legacy language names are also accepted:
unsupportedis treated assystemunsupported_scriptis treated asscript
aliasยถ
An alternate identifier for selecting the hook from the CLI.
If set, you can run the hook via either prek run <id> or prek run <alias>.
argsยถ
Extra arguments appended to the hookโs entry.
- Type: list of strings
Example:
envยถ
prek-only
env is a prek extension and may not be recognized by upstream pre-commit.
Extra runtime environment variables for the hook process.
- Type: map of string to string
Values override the existing process environment (including variables such as PATH).
They are applied when the hook runs, not when prek installs or prepares the hook environment.
For remote hooks, env may also be set by the hook author in
.pre-commit-hooks.yaml. Values from the project configuration are merged with
manifest values and override duplicate keys.
For docker / docker_image hooks, these variables are passed into the container rather than being applied to the container runtime command.
Example:
files / excludeยถ
Filters applied to candidate filenames.
filesselects which files are eligible for the hook.excluderemoves files matched byfiles.
If you use both global and hook-level filters, the effective behavior is โglobal filter first, then hook filterโ.
By default (and for compatibility with upstream pre-commit), these are regex strings.
As a prek extension, you can also specify globs using glob or a glob list.
See Top-level files and Top-level exclude for syntax notes and examples.
types / types_or / exclude_typesยถ
File-type filters based on identify tags.
Tip
Use prek util identify <path> to see how prek tags a file when youโre troubleshooting types filters.
Compared to regex-only filtering (files / exclude), tag-based filtering is often easier and more robust:
- tags can match by file extension and by shebang (for extensionless scripts)
- you can easily exclude things like symlinks or binary files
Common tags include:
-
file,text,binary,symlink,executable -
language-ish tags such as
python,rust,javascript,yaml,toml, ... -
types: all listed tags must match (logical AND) -
types_or: at least one listed tag must match (logical OR) -
exclude_types: tags that disqualify a file
How these combine:
files/exclude,types, andtypes_orare combined with AND.- Tags within
typesare combined with AND. - Tags within
types_orare combined with OR.
Defaults:
types:[file](matches all files)types_or:[]exclude_types:[]
These filters are applied in addition to regex filtering.
Examples:
[[repos]]
repo = "local"
hooks = [
# AND: must be under `src/` AND have the `python` tag
{
id = "lint-py",
name = "Lint (py)",
language = "system",
entry = "python -m ruff check",
files = "^src/",
types = ["python"],
exclude_types = ["symlink"]
},
# OR: match any of the listed tags under `web/`
{
id = "lint-web",
name = "Lint (web)",
language = "system",
entry = "npm run lint",
files = "^web/",
types_or = ["javascript", "jsx", "ts", "tsx"]
},
]
If you need to match a path pattern that doesnโt align with a hookโs default types (common when reusing an existing hook in a nonstandard way), override it back to โall filesโ and use files:
always_runยถ
Run the hook even when no files match.
- Type: boolean
- Default:
false
This is commonly used for hooks that check repository-wide state (for example, running a test suite) rather than operating on specific files.
pass_filenamesยถ
Controls whether prek appends the matching filenames to the command line.
- Type: boolean or positive integer
- Default:
truewhich passes all matching filenames
Set pass_filenames: false for hooks that donโt accept file arguments (or that discover files themselves).
Set pass_filenames: n (a positive integer) to limit each invocation to at most n filenames. When there are more matching files than n, prek splits them across multiple invocations. Those invocations may run concurrently unless require_serial is true. This is useful for tools that can only process a limited number of files at once.
Prek will automatically limit the number of filenames to ensure command lines donโt exceed the OS limit, even when pass_filenames: true.
prek-only
pass_filenames: n with a positive integer is a prek extension. Upstream pre-commit only accepts a boolean value.
stagesยถ
Declare which stages a hook is eligible to run in.
- Type: list of stage names
- Default: all stages
Allowed values:
manualcommit-msgpost-checkoutpost-commitpost-mergepost-rewritepre-commitpre-merge-commitpre-pushpre-rebaseprepare-commit-msg
When you run prek run --hook-stage <stage>, only hooks configured for that stage are considered.
require_serialยถ
Force a hook to run without parallel invocations (one in-flight process for that hook at a time).
- Type: boolean
- Default:
false
This is useful for tools that use global caches/locks or otherwise canโt handle concurrent execution.
priorityยถ
prek-only
priority controls prek's scheduler and does not exist in upstream pre-commit.
Each hook can set an explicit priority (a non-negative integer) that controls when it runs and with which hooks it may execute in parallel.
Scope:
priorityis evaluated within a single configuration file and is compared across all hooks in that file, even if they appear under differentrepos:entries.prioritydoes not coordinate across different config files. In workspace mode, each projectโs config file is scheduled independently.
Hooks run in ascending priority order: lower priority values run earlier. Hooks that share the same priority value run concurrently, subject to the global concurrency limit.
When priority is omitted, prek assigns an implicit value based on hook order to preserve sequential behavior.
Example:
[[repos]]
repo = "local"
hooks = [
{
id = "format",
name = "Format",
language = "system",
entry = "python3 -m ruff format",
always_run = true,
priority = 0,
},
{
id = "lint",
name = "Lint",
language = "system",
entry = "python3 -m ruff check",
always_run = true,
priority = 10,
},
{
id = "tests",
name = "Tests",
language = "system",
entry = "just test",
always_run = true,
priority = 20,
},
]
repos:
- repo: local
hooks:
- id: format
name: Format
language: system
entry: python3 -m ruff format
always_run: true
priority: 0
- id: lint
name: Lint
language: system
entry: python3 -m ruff check
always_run: true
priority: 10
- id: tests
name: Tests
language: system
entry: just test
always_run: true
priority: 20
Parallel hooks modifying files
If two hooks run in the same priority group and both mutate the same files (or depend on shared state), results are undefined. Use separate priorities to avoid overlap.
Hooks modifying files without a non-zero exit code
If a hook modifies files without emitting a non-zero exit code (e.g. ruff format), the priority group as a whole will fail.
It is not possible for prek to attribute the failure to a specific hook in the group which modified files.
Use separate priorities for clearer failure attribution.
require_serial is different
require_serial set to true prevents concurrent invocations of the same hook.
It does not prevent other hooks from running alongside it; use a unique priority if you need exclusivity.
fail_fastยถ
Hook-level fail-fast behavior.
- Type: boolean
- Default:
false
If true, a failure in this hook stops the run immediately.
verboseยถ
Print hook output even when the hook succeeds.
- Type: boolean
- Default:
false
log_fileยถ
Write hook output to a file when the hook fails (and also when verbose: true).
- Type: string path
descriptionยถ
Free-form description shown in listings / metadata.
- Type: string
language_versionยถ
Choose the language/toolchain version request for this hook.
- Type: string
- Default:
default
If not set, prek may use default_language_version for the hookโs language.
prek-only
language_version is treated as a version request, not a single pinned value. For languages that use semver requests, you can specify ranges (for example ^1.2, >=1.5, <2.0).
Special values:
default: use the languageโs default resolution logic.system: require a system-installed toolchain (no downloads).
Language-specific behavior:
- Python: passed to the Python resolver (for example
python3,python3.12, or a specific interpreter name). May trigger toolchain download. - Node: passed to the Node resolver (for example
20,18.19.0). May trigger toolchain download. - Go: uses Go version strings such as
1.22.1(downloaded if missing). - Rust: supports rustup toolchains such as
stable,beta,nightly, or versioned toolchains. - Other languages: parsed as a semver request and matched against the installed toolchain version.
Examples:
additional_dependenciesยถ
Extra dependencies for hooks that run inside a managed environment (for example Python or Node hooks).
- Type: list of strings
If you set this for a language that doesnโt support dependency installation, prek fails with a configuration error.
minimum_prek_versionยถ
prek-only
This is a prek-specific requirement gate. Upstream pre-commit does not have a hook-level minimum version key.
Require a minimum prek version for this specific hook.
- Type: string (version)
- Default: unset
For process environment controls, see the Environment Variable Reference.