A pre-commit hook is local, fast feedback — the earliest point in the entire development lifecycle a check can run. That speed constraint is also what determines which checks actually belong there.
What belongs in a pre-commit hook
The bar is: fast (sub-second to a couple seconds), high-confidence (very low false positive rate), and relevant to nearly every commit.
- Secret detection — scanning staged changes for patterns matching API keys, tokens, and credentials. Fast, and a leaked secret is exactly the kind of mistake worth catching before it's even committed locally.
- Basic linting for dangerous patterns — things like
eval()usage or obviously unsafe string concatenation into queries, where the check is simple and fast.
What doesn't belong there
- Dependency vulnerability scanning — usually too slow, and doesn't change on every commit.
- Full SAST scans — comprehensive static analysis is valuable but too slow for a pre-commit loop; it belongs in CI.
- Anything with meaningful false positives — a hook that blocks commits incorrectly trains developers to bypass it, which defeats the entire purpose.
Setting it up without creating friction
# .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
hooks:
- id: gitleaks
Tools like pre-commit (the framework) make this trivial to install consistently across a team, rather than relying on each developer to remember to run a script manually.
Remember: it's not an enforcement boundary
git commit --no-verify bypasses any pre-commit hook trivially. This is fine — the hook's job is fast local feedback, not the actual security guarantee. The real enforcement backstop is the same check running again in CI, where it can't be skipped with a flag.
Don't let it become a second full CI run locally
If a pre-commit hook takes 30+ seconds, developers will find it annoying enough to disable or route around. Keep the local hook narrow and fast, and trust CI to catch anything slower or more thorough that the hook intentionally left out.
The goal of a pre-commit hook isn't total coverage — it's catching the highest-confidence, most damaging mistakes (like a leaked secret) before they even leave a developer's machine.