| name | pre-commit |
| description | Set up full-stack pre-commit hooks with Lefthook, Ruff (Python), Biome (TypeScript/JavaScript), and commitlint (Conventional Commits). Use when user wants to add pre-commit hooks, set up commit-time quality gates, or configure linting and formatting checks before commits. |
Pre-commit Quality Gate
Set up a fast, parallel pre-commit pipeline for full-stack projects.
Tool choices: Lefthook (not Husky), Ruff (not Black/Flake8), Biome (not ESLint/Prettier).
Why: speed, simplicity, one tool per job.
Process
1. Detect project structure
Scan the repo to determine:
- Has Python backend? — look for
pyproject.toml, requirements.txt, or backend/ dir
- Has JS/TS frontend? — look for
package.json, frontend/, or src/ with .ts/.tsx files
- Has existing hooks? — check for
.husky/, lefthook.yml, .pre-commit-config.yaml
If existing hooks are found, ask the user before overwriting.
2. Install dependencies
Lefthook (always):
brew install lefthook
npm install -D lefthook
Python (if backend detected):
Frontend (if JS/TS detected):
npm install -D @biomejs/biome
Commitlint (always):
npm install -D @commitlint/cli @commitlint/config-conventional
3. Create lefthook.yml
Adapt based on detected structure. Full-stack example:
pre-commit:
parallel: true
commands:
ruff-check:
glob: "backend/**/*.py"
run: uvx ruff check {staged_files}
ruff-format:
glob: "backend/**/*.py"
run: uvx ruff format --check {staged_files}
biome-check:
glob: "frontend/**/*.{ts,tsx,js,jsx,json}"
root: "frontend/"
run: npx biome check {staged_files}
commit-msg:
commands:
commitlint:
run: npx commitlint --edit {1}
Adapt rules:
- Python-only project: remove
biome-check, remove root
- Frontend-only project: remove
ruff-* commands
- Monorepo: adjust
glob and root to match directory layout
4. Create commitlint.config.mjs
export default {
extends: ["@commitlint/config-conventional"],
rules: {
"scope-empty": [2, "never"],
"subject-max-length": [2, "always", 72],
},
};
Ask the user what scopes to enforce. If unclear, omit scope-enum and only enforce scope-empty.
5. Install hooks and verify
lefthook install
Run a smoke test:
lefthook run pre-commit
6. Commit the setup
Stage all config files and commit:
chore: add pre-commit hooks (lefthook + ruff + biome + commitlint)