Skip to content
Back to skills

Git Hooks

ASecurity

Manage pre-commit hooks, performance optimization, and temp commits. Use when asked about "pre-commit slow", "commit taking forever", "skip hooks", "bypass pre-commit", "optimize commits", or multi-agent workflows. Covers fast Prettier-only hook, ESLint performance issues, and CI delegation strategy.

  • 666 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added February 8, 2026
developmentjavascripttypescriptrustgojavabashgitapiperformance

Works with

  • api

Security analysis

A100/100

Scanned February 12, 2026

npx -y skills add majiayu000/claude-skill-registry --skill git-hooks --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Git Hooks?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Git Hooks
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-git-hooks/badge)](https://www.skillsdirectory.com/skills/majiayu000-git-hooks)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: git-hooks
description: Manage pre-commit hooks, performance optimization, and temp commits. Use when asked about "pre-commit slow", "commit taking forever", "skip hooks", "bypass pre-commit", "optimize commits", or multi-agent workflows. Covers fast Prettier-only hook, ESLint performance issues, and CI delegation strategy.
---

# Git Hooks Management

## Overview

This monorepo uses a **fast pre-commit hook** that only runs Prettier (~1-2 seconds). ESLint, typecheck, and tests run in CI.

**Why?** ESLint with TypeScript type-aware rules takes ~2 minutes per file due to project-wide type loading.

## Quick Reference

### Normal Commit (~1-2 seconds)

```bash
git commit -m "feat: add feature"
```

### Bypass All Checks (instant)

```bash
git commit --no-verify -m "message"
# or
TEMP_COMMIT=1 git commit -m "[temp] message"
```

### Auto-bypass Prefixes

Commits starting with these bypass the hook:

- `[temp]` - temporary, will squash
- `[wip]` - work in progress
- `[skip-ci]` - skip CI
- `[no-verify]` - explicit bypass

## What Runs Where

| Check      | Pre-commit    | CI  | Editor |
| ---------- | ------------- | --- | ------ |
| Prettier   | ✅ ~1s        | ✅  | ✅     |
| ESLint     | ❌ (too slow) | ✅  | ✅     |
| TypeScript | ❌ (too slow) | ✅  | ✅     |
| Tests      | ❌            | ✅  | manual |

## Performance History

Original hook: **~3-5 minutes**

- lint-staged (ESLint): ~2 minutes
- Turbo typecheck: ~2 minutes
- Vitest tests: ~90 seconds

Optimized hook: **~1-2 seconds**

- Prettier only on staged files

## Before Optimizing Your Hook

Benchmark each step to identify the bottleneck:

```bash
# Benchmark lint-staged
time npx lint-staged

# Benchmark ESLint directly on a single file
time pnpm exec eslint packages/core/src/index.ts --fix

# Benchmark Prettier directly
time pnpm exec prettier packages/core/src/index.ts --write

# Benchmark typecheck
time pnpm turbo run typecheck --filter='[HEAD]'
```

## Performance Comparison (This Repo)

| Approach                             | Time  | Notes                   |
| ------------------------------------ | ----- | ----------------------- |
| Full lint-staged (ESLint + Prettier) | ~2:05 | ESLint type-aware rules |
| ESLint alone on 1 file               | ~2:00 | Type loading dominates  |
| Prettier alone on 1 file             | ~0.3s | No type loading         |
| Prettier-only hook                   | ~1-2s | **Current approach**    |

## Why ESLint is Slow

The `.eslintrc.js` has type-aware linting enabled:

```javascript
parserOptions: {
  project: './tsconfig.eslint.json',  // This loads entire TS project
}
```

This makes ESLint load and parse the entire TypeScript project for every file. In a monorepo with many packages, this can take 2+ minutes even for a single file.

### Diagnosing Slow ESLint Rules

```bash
# Show timing for each rule
TIMING=1 pnpm exec eslint packages/core/src/index.ts

# Output shows which rules are slowest:
# Rule                          | Time (ms)
# @typescript-eslint/no-unsafe* | 45000ms  <- type-aware rules
```

### Options to Fix

1. **Remove `project` option** - disables type-aware rules, fastest
2. **Use `TIMING=1`** - identify and disable specific slow rules
3. **Skip ESLint in pre-commit** - run in CI only (current approach)
4. **Switch to Biome** - faster Rust-based linter

## Manual Checks Before PR

Run full validation before creating PRs:

```bash
# Full CI-equivalent check
pnpm turbo run typecheck lint test

# Or individually
pnpm exec eslint .
pnpm turbo run typecheck
pnpm test
```

## Hook Configuration

**Location:** `.husky/pre-commit`

Current hook does:

1. Get staged `.ts`, `.tsx`, `.json`, `.md`, `.yml` files
2. Run Prettier on them
3. Re-stage formatted files

## Troubleshooting

### Hook still slow?

Check if someone re-added lint-staged:

```bash
grep -n "lint-staged\|eslint" .husky/pre-commit
```

### Need ESLint locally?

Run it manually on specific files:

```bash
pnpm exec eslint packages/core/src/myfile.ts
```

### CI failing but local passes?

The hook doesn't run ESLint/typecheck. Run locally:

```bash
pnpm turbo run typecheck lint
```

### Common ESLint Errors in CI

**no-case-declarations**: Lexical declarations (`const`, `let`, `class`, `function`) in `switch` case blocks must be wrapped in braces:

```typescript
// ❌ Bad - ESLint error
switch (method) {
  case 'storage.get':
    const value = await db.get(key); // Error: Unexpected lexical declaration
    return res.json({ data: value });
}

// ✅ Good - wrap case block in braces
switch (method) {
  case 'storage.get': {
    const value = await db.get(key);
    return res.json({ data: value });
  }
}
```

This pattern is common in route handlers and bridge API implementations.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.