The Nightmare: "I forgot to run the linter"
We've all been there: you’ve been coding for three hours, you’re in the flow, and you finally hit git push. Five minutes later, you get a notification: CI/CD Pipeline Failed.
The culprit? A missing semicolon, a dangling console.log, or a single failing unit test.
This is more than just a minor annoyance. It wastes expensive CI/CD compute minutes, clutters your git history with "fix lint" commits, and forces your teammates to wait on a "broken" build. In a professional system, human memory is a single point of failure. We need to automate the "Bouncer" role.
The Solution: Git Hooks (The Bouncer for your Repo)
Git hooks are scripts that run automatically whenever a specific action occurs in your git lifecycle (like commit, push, or merge).
Instead of relying on a developer to remember to run npm run lint, we bake it into the system so that the code literally cannot be committed unless it passes your quality standards.
The Power Couple: Husky + Lint-Staged
While Git has native hooks, they are notoriously difficult to share with a team because the .git/hooks folder isn't tracked by version control. That’s where these tools come in:
-
Husky: It "syncs" your git hooks across the entire team. When a new dev runs
npm install, Husky automatically sets up the hooks on their local machine. -
Lint-Staged: Running a full linter or test suite on a massive project can take minutes. Lint-Staged is the "optimizer"—it ensures you only run checks on the files you are currently staging (
git add), keeping your workflow lightning-fast.
Implementation Example:
In your package.json, a typical setup looks like this:
{
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"pre-push": "npm test"
}
},
"lint-staged": {
"*.{js,ts,tsx}": [
"eslint --fix",
"prettier --write"
]
}
}
Why this is "System" Design:
1. Enforced Standards (Zero Trust)
In a robust system design, you don't trust "good intentions." No matter who joins the team—a senior architect or a junior intern—they are forced to follow the same styling, linting, and testing rules. This creates a uniform codebase that is easier to maintain.
2. CI/CD Pipeline Efficiency
Cloud compute for CI/CD pipelines (GitHub Actions, CircleCI, etc.) costs money and time. By catching "stupid" errors locally on the developer's laptop, your expensive remote runners only deal with code that is already verified. This creates a faster feedback loop for the entire team.
3. Preventing "Obvious" Regressions
A pre-push hook that runs your unit tests acts as a safety net. It prevents you from accidentally pushing a breaking change to the main branch, ensuring that the shared source of truth remains stable at all times.
Pro-Tip: The "Atomic" Commit
By using Git hooks to enforce linting and formatting, every commit in your history becomes "clean." This makes git bisect (finding the commit that introduced a bug) and git revert significantly easier because you aren't sifting through "formatting fix" noise.
Takeaway: A system is only as reliable as its automated safeguards. Git hooks turn your repository from a "free-for-all" into a high-integrity environment.
Top comments (0)