Oxlint and Lefthook Pre-Commit Automation#
Date: 2026-02-10 Status: Approved for Implementation
Goal#
Add automated linting and testing to pre-commit hooks. Catch style issues, type errors, and test failures before they reach the repository.
Architecture#
Tools Selected#
Oxlint — Rust-based linter, runs in milliseconds. Uses recommended preset to catch common issues without overwhelming developers.
Lefthook — Git hook manager written in Go. Executes checks in parallel, maximizing speed in monorepo environments.
Configuration Location#
Single configuration at monorepo root:
.oxlintrc.json— Lint rules inherited by all packages.lefthook.yml— Hook definitions and execution strategy- Root
package.json— Tool dependencies and prepare script
Per-package additions:
lint:fixscript in eachapps/*/package.jsonandpackages/*/package.json
Pre-Commit Hook Strategy#
Execution Flow#
On git commit, lefthook runs three checks in parallel:
- Lint staged files —
oxlinton staged TypeScript/JavaScript files (< 1s) - Type check affected packages —
tsc --noEmiton packages with changes - Test affected packages —
viteston packages with changes
All checks must pass. Any failure blocks the commit.
Affected Package Detection#
Use turbo's filter syntax to test only packages with staged changes:
pnpm turbo test --filter=...[HEAD] --force
pnpm turbo lint --filter=...[HEAD]
This prevents running all tests when only one package changed.
Parallel Execution#
Lefthook runs all three checks simultaneously. First failure stops execution and displays errors. This design minimizes wait time while maintaining thoroughness.
Configuration Files#
.oxlintrc.json#
{
"rules": {
"oxc/recommended": "error"
},
"env": {
"node": true,
"es2022": true
},
"ignorePatterns": ["dist", "node_modules", ".turbo"]
}
Rules set to error level — violations block commits immediately. No migration period needed (team consists of one developer and AI assistants).
.lefthook.yml#
pre-commit:
parallel: true
commands:
lint:
glob: "*.{ts,tsx,js,jsx}"
run: npx oxlint {staged_files}
typecheck:
glob: "*.{ts,tsx}"
run: pnpm turbo lint --filter=...[HEAD]
test:
glob: "*.{ts,tsx,js,jsx}"
run: pnpm turbo test --filter=...[HEAD] --force
Root package.json Updates#
Add dependencies:
{
"devDependencies": {
"oxlint": "latest",
"lefthook": "^1.9.0"
},
"scripts": {
"prepare": "lefthook install"
}
}
The prepare script auto-installs git hooks after pnpm install.
Per-Package Scripts#
Add to each apps/*/package.json and packages/*/package.json:
{
"scripts": {
"lint:fix": "oxlint --fix src/"
}
}
Developers run this manually to auto-fix lint violations before committing.
Developer Workflow#
Normal Commit Flow#
- Make changes
- Stage files with
git add - Run
git commit - Lefthook executes lint, typecheck, and test in parallel
- If all pass, commit succeeds
- If any fail, commit blocks — errors display in terminal
Fixing Lint Violations#
Auto-fix safe issues:
pnpm turbo lint:fix
Or fix a specific package:
pnpm --filter @atbb/appview lint:fix
Then retry the commit.
Fixing Type Errors#
Review TypeScript errors in terminal output. Fix manually, then retry commit.
Fixing Test Failures#
Review failing tests in terminal output. Fix code or tests, then retry commit.
Emergency Bypass#
Use git commit --no-verify to skip hooks. Discouraged but available for urgent situations.
Installation#
After merging this change:
- Developers pull latest
main - Run
pnpm install— thepreparescript installs lefthook hooks automatically - Hooks activate immediately for next commit
No additional setup required.
Documentation Updates#
Add to CLAUDE.md under a new "Pre-Commit Checks" section:
- Explain what runs on every commit (lint, typecheck, test)
- Show how to auto-fix lint issues (
pnpm turbo lint:fix) - Document bypass mechanism (
git commit --no-verify) - Link to
.lefthook.ymlfor full configuration
Benefits#
Speed — Oxlint runs in milliseconds. Lefthook parallelizes checks. Turbo filters to affected packages only.
Safety — Catches style violations, type errors, and test failures before they enter the repository.
Consistency — All commits meet the same quality bar automatically.
Low friction — Most issues auto-fix with lint:fix. Hook bypass available when needed.