pc-init#
Generate a pre-commit or prek .pre-commit-config.yaml for your project from curated language and framework presets — so you get the right linters, formatters, and quality tools wired up with a single command instead of copying configs between repos.
Works with prek and pre-commit
Motivation#
Every new repository needs a .pre-commit-config.yaml.
Each language and framework has its own recommended linters, formatters, and quality tools, each with its own hook URL and revision.
pc-init encodes those choices in version-controlled presets so you run one command instead of copying configs and looking up hook URLs.
The bundled presets pin specific hook revisions — run pre-commit autoupdate or prek autoupdate after generation to pull in the latest versions.
Alternatives#
If you'd rather run one all-in-one Docker-based linter instead of wiring up individual pre-commit hooks, see MegaLinter. pc-init takes the opposite approach: it generates a .pre-commit-config.yaml of individually-pinned, curated hooks that run natively via pre-commit/prek, so you can see, version, and update each tool independently.
Awesome Pre-commit Hooks#
The curated hooks bundled with pc-init are also published as a standalone reference at awesome-pre-commit-hooks — a browsable list of every hook organised by language and framework.
Installation#
uv tool install pc-init
Quickstart#
In an existing repository, let pc-init detect what's there and generate a config in one command:
cd my-project
pc-init --detect
Or specify languages and frameworks explicitly:
pc-init --lang py --framework django
Then install the hooks:
pre-commit install
# or
prek install
Usage#
Usage: pc-init [OPTIONS] COMMAND [ARGS]...
Generate a .pre-commit-config.yaml for your project.
Options:
--lang TEXT Language preset to include (repeatable, or
comma-delimited: --lang=py,js). Run `pc-init list` to
see supported values from the active catalog.
--framework TEXT Framework preset to layer on top of language baselines
(repeatable, or comma-delimited: --framework=react,django).
Run `pc-init list` to see supported values from the
active catalog.
--force Overwrite existing .pre-commit-config.yaml without
prompting.
--detect Auto-detect languages and frameworks from the current
directory and merge them with any explicitly supplied
--lang/--framework values.
--output TEXT Output file path. [default: .pre-commit-config.yaml]
--presets TEXT Preset catalog to use. Accepts a local directory path or
a git repository URL (https://, git@, git://, ssh://).
The directory / repo root must contain lang/ and
framework/ subdirectories. Defaults to the bundled
presets.
--version Show version and exit.
--help Show this message and exit.
Commands:
list List available language and framework presets in the active catalog.
List available presets#
Run pc-init list to discover all supported languages and frameworks in the active catalog (bundled or custom):
pc-init list
Languages:
cpp, css, docker, go, img, js, kt, make, md, nb, proto, py, rb, ru, sh, sql, swift, tf, toml, ts, yaml
Frameworks:
ansible, django, git, k8s, react, sphinx
Use --presets to list what a custom catalog provides:
pc-init list --presets /path/to/my-presets
pc-init list --presets https://github.com/org/my-presets
Supported presets#
Languages — pass as --lang:
| ID | Language |
|---|---|
py | Python |
js | JavaScript |
go | Go |
ru | Rust |
sh | Shell / Bash |
ts | TypeScript |
nb | Jupyter Notebooks |
md | Markdown |
img | Images |
docker | Docker |
sql | SQL |
tf | Terraform |
toml | TOML |
yaml | YAML |
make | Makefiles |
rb | Ruby |
cpp | C / C++ |
proto | Protocol Buffers |
swift | Swift |
kt | Kotlin |
css | CSS / SCSS / Sass |
Language aliases python, javascript, typescript, rust, ruby, golang, shell, bash, image, notebook, jupyter, dockerfile, makefile, terraform, c, c++, and kotlin are also accepted.
Frameworks — pass as --framework:
| ID | Framework |
|---|---|
react | React |
django | Django |
sphinx | Sphinx documentation |
git | Commit message linting |
k8s | Kubernetes |
ansible | Ansible |
Auto-detecting languages and frameworks#
--detect scans the current directory, infers languages from file extensions and frameworks from indicator files, and uses the results exactly as if you had passed them with --lang and --framework.
pc-init --detect
Detected languages: md, py, yaml, sh, js
Detected frameworks: git
Generated .pre-commit-config.yaml with languages: md, py, yaml, sh, js and frameworks: git
Detected values are merged with any explicitly supplied flags — duplicates are dropped:
pc-init --detect --lang sql # adds sql on top of whatever is detected
If the file already exists and differs, the suggested overwrite command uses explicit --lang and --framework values so the re-run is fully deterministic:
Run with --force to overwrite '.pre-commit-config.yaml'.
Try: pc-init --lang=md,py,yaml,sh,js --framework=git --force
Language detection is based on file extensions (common vendored directories such as .git, node_modules, .venv, __pycache__, and dist are skipped):
| Extension(s) | Language |
|---|---|
.py, .pyi | py |
.js, .mjs, .cjs, .jsx | js |
.ts, .tsx | ts |
.go | go |
.rs | ru |
.rb | rb |
.c, .h, .cpp, .cc, .cxx, .hpp, .hh, .hxx | cpp |
.proto | proto |
.swift | swift |
.kt, .kts | kt |
.css, .scss, .sass | css |
.sh, .bash | sh |
.sql | sql |
.tf, .tfvars | tf |
.md, .markdown | md |
.ipynb | nb |
.yaml, .yml | yaml |
.r | r |
.png, .jpg, .jpeg, .gif, .webp, .svg | img |
Dockerfile (filename) | docker |
Makefile (filename) | make |
Framework detection is based on indicator files:
| Indicator | Framework |
|---|---|
manage.py at the repo root | django |
package.json with react in dependencies or devDependencies | react |
conf.py (root or docs/) containing sphinx | sphinx |
Any .yaml/.yml file outside .github/ containing apiVersion: and kind: | k8s |
.github/workflows/ directory with at least one .yml file | git |
ansible.cfg at the repo root | ansible |
Language suggestions for frameworks#
Some framework presets declare the languages they are typically used with.
If none of your --lang selections match, pc-init prints an informational note and a ready-to-run command that adds the missing languages:
Note: preset 'react' recommends adding: --lang=js,ts
Try: pc-init --lang=go,js,ts --framework=react
The suggested command preserves your existing --lang values so it is safe to run with --force — no hooks you already selected will be removed.
Pass --recommended to apply all suggestions automatically in a single run:
pc-init --lang go --framework react --recommended
You can also omit --lang entirely when using --recommended with at least one framework — the recommended languages are used as the starting set:
pc-init --framework django --recommended
Examples#
Auto-detect everything:
pc-init --detect
Auto-detect and add an extra language:
pc-init --detect --lang sql
Python project:
pc-init --lang py
JavaScript project with React:
pc-init --lang js --framework react
Python + Django, overwriting an existing config:
pc-init --lang py --framework django --force
Multiple languages (two equivalent forms):
pc-init --lang py --lang js
pc-init --lang=py,js
Django project, letting pc-init pick the language automatically:
pc-init --framework django --recommended
Custom presets#
Point --presets at a local directory or a git repository that contains lang/ and framework/ subdirectories in the same layout as the bundled presets.
Local directory:
pc-init --lang py --presets /path/to/my-presets
Git repository:
pc-init --lang py --presets https://github.com/org/my-presets
Contributing#
See CONTRIBUTING.md for development setup, preset guidelines, and the pull request checklist.