AI coding assistants write syntactically correct code most of the time. They are considerably less reliable about respecting your project's import conventions, naming patterns, or type contracts. That gap is exactly what pre-commit hooks close.
This is a step-by-step guide to setting up pre-commit hooks for a team that uses AI coding tools. The setup applies to both Python and JavaScript/TypeScript projects. The concepts transfer to any language with a linter.

Photo by Nemuel Sereti on Pexels
Why Pre-Commit Hooks Matter More With AI Tools
Without AI tools, style and convention drift usually happens slowly. One developer's personal habits creep in here and there, and code review catches most of it.
With AI tools, convention drift can happen fast. A developer working with GitHub Copilot or Cursor accepts 20 suggestions in an afternoon. Each suggestion is syntactically valid and logically plausible. But several of them use import paths that differ from your project's convention, name variables using a pattern the tool learned from a different codebase, or skip error handling that your team has agreed is mandatory.
By the time this reaches code review, the reviewer has to evaluate each deviation individually: is this intentional, or is it AI drift? The answer is usually "AI drift," but confirming that takes time. Pre-commit hooks catch the detectable violations automatically, so reviewers can focus on logic rather than style.
Step 1: Install the pre-commit Framework
The pre-commit framework is the standard tool for managing Git hooks. Install it with pip:
pip install pre-commit
Or if you are managing Python tool dependencies with a dev dependencies group:
pip install --group dev pre-commit
For teams on Node.js projects that prefer keeping everything in package.json, Husky is the equivalent. The configuration differs slightly, but the concept is the same: a hook runs before each commit and can block the commit if checks fail.
Add a .pre-commit-config.yaml file to the root of your repository. This file defines which hooks run and in what order.
Step 2: Configure Your Linter
For Python projects, add ruff as your primary lint and format check:
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.4
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
Ruff is a fast Python linter that combines flake8, isort, and several other tools. For teams on older setups that prefer flake8 directly:
repos:
- repo: https://github.com/PyCQA/flake8
rev: 7.0.0
hooks:
- id: flake8
For TypeScript/JavaScript projects, add ESLint:
repos:
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v8.57.0
hooks:
- id: eslint
files: \.[jt]sx?$
types: [file]
ESLint is the standard linter for JavaScript and TypeScript. Configure your .eslintrc as you normally would; the pre-commit hook runs it on staged files only, which keeps it fast.
Step 3: Add a Type Checker
Type checking is where AI tools tend to introduce the most subtle errors. A suggestion might use a method that doesn't exist on the type the tool inferred, or assume a nullable field is always present.
For Python projects, add mypy:
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.10.0
hooks:
- id: mypy
additional_dependencies: [types-requests, types-PyYAML]
Adjust additional_dependencies to include the type stubs your project uses. mypy will catch cases where AI-generated code calls methods that do not exist on a type, passes arguments in the wrong order, or skips null checks.
For TypeScript projects, tsc handles type checking as part of the normal build. You can add it to pre-commit directly:
- repo: local
hooks:
- id: tsc
name: TypeScript type check
language: node
entry: npx tsc --noEmit
types: [ts, tsx]
pass_filenames: false
TypeScript type errors from AI suggestions are common, especially when the tool generates code that interfaces with an existing typed module it did not see in full context.
Step 4: Install the Hooks
Once .pre-commit-config.yaml is configured, install the hooks into your local Git repository:
pre-commit install
This adds a .git/hooks/pre-commit script that runs automatically before each commit. Every developer on the team needs to run pre-commit install once after cloning the repository. Add this to your contributing guide or your repository's Makefile setup target.
To verify the hooks run correctly against the current staged files:
pre-commit run --all-files
This runs all configured hooks against every file in the repository. Expect some failures on first run in an existing codebase; fix them or add exceptions as needed before requiring the hooks in CI.
Step 5: Add the Check to CI
Pre-commit hooks run locally by default. If a developer bypasses them (intentionally or by committing directly without the hooks installed), violations can still reach your pull request.
Adding a CI check ensures the hooks run on every PR regardless of local setup. In GitHub Actions, add a job like this:
name: pre-commit
on: [pull_request]
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- uses: pre-commit/action@v3.0.1
This uses the official pre-commit/action to run the same hooks your developers run locally. Failed checks block the PR. Passed checks mean the linting and type checks have been verified end to end.
Keeping Hooks Fast
One failure mode with pre-commit setups is hooks that run too slowly. If committing takes 20-30 seconds every time, developers start using git commit --no-verify to skip the hooks. That defeats the purpose entirely.
Configure hooks to check only staged files where possible (most hooks do this by default). Avoid running expensive operations like full test suites in pre-commit. Those belong in CI. Pre-commit should run in under 5 seconds on a typical commit, which means linting and type checking staged files only.
If a specific hook is slow, check whether it supports a files or types filter to narrow its scope. Running ESLint on only .ts and .tsx files is faster than running it on every file in the repository.
For a broader picture of how pre-commit hooks fit into a full Git workflow for AI-assisted teams, see How to Integrate AI Coding Tools Into Your Git Workflow Without Losing Control. The AI automation agency 137Foundry helps engineering teams set this up alongside the rest of their AI tooling integration.

Photo by cottonbro studio on Pexels
Summary
Pre-commit hooks are a practical, low-overhead guardrail for AI-assisted codebases. The setup takes an hour and runs silently after that. The configuration described here covers the most common failure modes in AI tool output: style drift, import convention violations, and type errors.
The investment is a .pre-commit-config.yaml, a pre-commit install in your setup instructions, and a CI job. The return is a class of review comments that stops appearing because the automated check catches them first.
One last note on team adoption: pre-commit works best when it is part of your repository setup documentation rather than something developers discover on their own. Add it to your CONTRIBUTING.md, include it in your onboarding checklist, and add a make setup target that runs pre-commit install automatically. When every developer has the hooks installed from day one, the coverage is consistent and the review benefits are immediate for the entire team rather than just the developers who remembered to run the install command.
Top comments (0)