DEV Community

upa_rupa
upa_rupa

Posted on

Auto-Configure Git Hooks for Your Entire Team with Just npm install

No more "Git hooks weren't working on my machine"

In team development, running tests locally before pushing is crucial — it reduces CI wait times and helps you move faster.

The problem? The .git/hooks/ directory is not tracked by Git. Every developer has to manually set up hooks after cloning a repo, which leads to familiar issues:

  • Forgotten setup: New team members or people rebuilding their environment skip the manual step
  • Stale hooks: When hook scripts are updated, getting everyone to re-apply the changes manually is a losing battle
  • No enforcement: Hook setup is left to individual discretion, making it hard to guarantee consistent quality across the team

Even with CI in place, slow feedback loops hurt if local checks keep getting skipped.

The fix: embed Git hook setup into npm install — an operation everyone already runs — so the entire team stays in sync without thinking about it.

And we'll do it without any extra libraries like Husky, using only Git's built-in features and npm scripts.

Local Git hooks and GitHub Actions: Better Together

Running tests locally doesn't replace CI — they serve different purposes and work well together.

Aspect GitHub Actions Local Git hooks
When it runs After push Before push
Feedback speed Must wait for CI to spin up Instant, right on your machine
Environment consistency Unified, reproducible environment Depends on local setup
Enforcement Strong (cannot be bypassed) Medium (--no-verify can skip it)
Resource cost Consumes CI minutes Only your local machine

Fast local feedback plus reliable CI checks — together they cover both speed and consistency.

The Setup: core.hooksPath + npm prepare

Just three steps:

1. Create a hooks directory in your project

mkdir -p .githooks
Enter fullscreen mode Exit fullscreen mode

2. Write your hook scripts

Example: a pre-push hook that runs tests before every push

# .githooks/pre-push
#!/bin/bash

echo "🧪 Running tests before push..."

# Run project tests
npm test

if [ $? -ne 0 ]; then
  echo "❌ Tests failed. Push aborted."
  exit 1
fi

echo "✅ All tests passed. Proceeding with push."
Enter fullscreen mode Exit fullscreen mode

Make it executable:

chmod +x .githooks/pre-push
Enter fullscreen mode Exit fullscreen mode

3. Add a prepare script to package.json

{
  "scripts": {
    "prepare": "git config core.hooksPath .githooks"
  }
}
Enter fullscreen mode Exit fullscreen mode

That's it.

Why This Works

How prepare behaves:

  • Runs automatically after npm install
  • Also runs after npm ci
  • Running npm install right after cloning is second nature — making this a reliable trigger

What core.hooksPath does:

  • Points Git to any directory instead of the default .git/hooks/
  • By pointing to .githooks/ in the project root, the hook scripts themselves become Git-tracked — updates to scripts propagate to everyone via the repository

Combined: clone the repo, run npm install, and Git hooks are active. No extra steps.

Simpler Onboarding for New Team Members

The old way:

  1. Clone the repository
  2. npm install
  3. "Oh, the README says to set up Git hooks..."
  4. Manually run git config core.hooksPath .githooks
  5. (Half the team forgets)

With this setup:

  1. Clone the repository
  2. npm installdone

Onboarding instructions become: "just run npm install."

Monorepo Support

If you have multiple sub-projects under a single root:

project-root/
├── .githooks/
│   └── pre-push
├── frontend/
│   └── package.json
├── backend/
│   └── package.json
└── package.json  ← configure here
Enter fullscreen mode Exit fullscreen mode

Configure it in the root package.json and it works as long as you run npm install at the root.

A Real-World pre-push Hook

#!/bin/bash

echo "🧪 Running pre-push checks..."

# Frontend tests
if [ -d "frontend" ]; then
  echo "📦 Testing frontend..."
  cd frontend && npm test
  if [ $? -ne 0 ]; then
    echo "❌ Frontend tests failed."
    exit 1
  fi
  cd ..
fi

# Backend tests
if [ -d "backend" ]; then
  echo "📦 Testing backend..."
  cd backend && npm test
  if [ $? -ne 0 ]; then
    echo "❌ Backend tests failed."
    exit 1
  fi
  cd ..
fi

echo "✅ All checks passed!"
Enter fullscreen mode Exit fullscreen mode

Summary

  1. Don't rely on CI alone — run tests locally for fast feedback
  2. Create a .githooks/ directory and place your hook scripts there
  3. Set "prepare": "git config core.hooksPath .githooks" in package.json
  4. Everyone on the team gets Git hooks automatically on npm install

Pushing without running tests becomes the exception, not the norm — and "I forgot to set up hooks" stops happening.


This article was originally published in Japanese at archelon-inc.jp.

Top comments (0)