husky の使い方

Modern native Git hooks

v9.1.7/週MITLint / Formatter
AI生成コンテンツ

この記事はAIによって生成されました。内容の正確性は保証されません。最新の情報は公式ドキュメントをご確認ください。

husky の使い方 — モダンなGitフックをプロジェクトに簡単導入

一言でいうと

huskyは、Gitフック(pre-commit、commit-msgなど)をプロジェクト内で簡単に管理・共有できるnpmパッケージです。コミット前のlintやテスト実行を自動化し、チーム全体でコード品質を担保する仕組みを数コマンドで構築できます。

どんな時に使う?

  • コミット前にlint/フォーマットを自動実行したいpre-commitフックでESLintやPrettierを走らせ、品質の低いコードがリポジトリに入るのを防ぐ
  • コミットメッセージの規約を強制したいcommit-msgフックでConventional Commitsなどのフォーマットをチェックする(commitlintとの併用)
  • プッシュ前にテストを実行したいpre-pushフックでユニットテストを走らせ、壊れたコードがリモートに上がるのを防ぐ

インストール

# npm
npm install --save-dev husky

# yarn
yarn add --dev husky

# pnpm
pnpm add --save-dev husky

初期セットアップ

v9系ではhusky initコマンドで初期化するのが推奨されています。

npx husky init

このコマンドを実行すると、以下が自動的に行われます:

  1. .husky/ディレクトリが作成される
  2. .husky/pre-commitにサンプルのフックスクリプトが生成される
  3. package.jsonscripts"prepare": "husky"が追加される

prepareスクリプトにより、npm install実行時にGitフックが自動で有効化されます。チームメンバーがリポジトリをクローンして依存をインストールするだけで、フックが機能する仕組みです。

基本的な使い方

最も一般的なパターンとして、コミット前にlint-stagedを実行する例を紹介します。

# huskyの初期化
npx husky init

# pre-commitフックの内容を書き換え
echo "npx lint-staged" > .husky/pre-commit

.husky/pre-commitファイルの中身:

npx lint-staged

package.json側の設定例:

{
  "scripts": {
    "prepare": "husky"
  },
  "devDependencies": {
    "husky": "^9.1.7",
    "lint-staged": "^15.0.0",
    "eslint": "^8.0.0",
    "prettier": "^3.0.0"
  },
  "lint-staged": {
    "*.{ts,tsx}": ["eslint --fix", "prettier --write"],
    "*.{json,md}": ["prettier --write"]
  }
}

これでgit commitを実行するたびに、ステージングされたファイルに対してESLintとPrettierが自動で走ります。

よく使うAPI(フック設定パターン)

huskyはAPIというよりも、.husky/ディレクトリ内のシェルスクリプトでフックを定義します。以下によく使うパターンを示します。

1. pre-commit — コミット前のチェック

# .husky/pre-commit
npx lint-staged
# フックファイルの作成
echo "npx lint-staged" > .husky/pre-commit

2. commit-msg — コミットメッセージの検証

commitlintと組み合わせて、コミットメッセージの規約を強制します。

# .husky/commit-msg
npx --no -- commitlint --edit $1
echo 'npx --no -- commitlint --edit $1' > .husky/commit-msg

commitlintの設定例(commitlint.config.ts):

import type { UserConfig } from "@commitlint/types";

const config: UserConfig = {
  extends: ["@commitlint/config-conventional"],
};

export default config;

3. pre-push — プッシュ前のテスト実行

# .husky/pre-push
npm test
echo "npm test" > .husky/pre-push

4. 複数コマンドの実行

1つのフックで複数の処理を順番に実行できます。

# .husky/pre-commit
npm run typecheck
npx lint-staged

いずれかのコマンドが非ゼロの終了コードを返すと、コミットは中断されます。

5. フックの一時的なスキップ

特定のコミットでフックをスキップしたい場合は、Git標準の--no-verifyフラグを使います。

# pre-commitとcommit-msgフックをスキップ
git commit -m "wip: 作業中" --no-verify

# pre-pushフックをスキップ
git push --no-verify

環境変数でも制御可能です:

HUSKY=0 git commit -m "huskyをスキップ"

類似パッケージとの比較

特徴husky (v9)simple-git-hookslefthook
設定方法.husky/ディレクトリ内のシェルスクリプトpackage.jsonまたは設定ファイルYAML設定ファイル
依存サイズ非常に軽量非常に軽量Go製バイナリ(やや大きい)
並列実行非対応(シェルスクリプト次第)非対応対応
Node.js依存ありありなし(Go製)
エコシステム最大(lint-staged, commitlint等との連携実績豊富)小規模中規模
学習コスト低い非常に低いやや高い
モノレポ対応可能(設定が必要)限定的充実

選定の目安:

  • husky — 最も広く使われており、情報量が豊富。一般的なプロジェクトにはこれで十分
  • simple-git-hooks — 設定ファイルが1つで済むシンプルさを重視する場合
  • lefthook — モノレポや並列実行など高度な要件がある場合

注意点・Tips

v8以前からの移行に注意

v9ではセットアップ方法が大きく変わりました。v8以前のhusky install.husky/_/husky.shを使ったパターンは不要になっています。既存プロジェクトを移行する場合は、古い.husky/ディレクトリを削除してからnpx husky initをやり直すのが確実です。

CI環境でのフック無効化

CI/CD環境ではGitフックを実行する必要がありません。huskyはnpm ci実行時(prepareスクリプト経由)にフックをセットアップしようとしますが、CI環境では以下のいずれかで対処します。

# 方法1: 環境変数で無効化
HUSKY=0 npm ci

# 方法2: npm ciの--ignore-scriptsフラグ(他のスクリプトも無効になる点に注意)
npm ci --ignore-scripts

GUI Gitクライアントでの動作

SourceTreeやVS CodeのGit機能など、GUIクライアントからコミットした場合もフックは実行されます。ただし、GUIクライアントがNode.jsのPATHを正しく認識できない場合があります。その場合は~/.huskyrc(非推奨)ではなく、フックスクリプト内でPATHを明示的に設定してください。

# .husky/pre-commit
export PATH="/usr/local/bin:$PATH"
npx lint-staged

lint-stagedとの併用がベストプラクティス

pre-commitでプロジェクト全体にlintを走らせると、大規模プロジェクトでは時間がかかりすぎます。lint-stagedを使えば、ステージングされたファイルだけを対象にできるため、コミット体験を損ないません。

モノレポでの使い方

モノレポでは、Gitフックはリポジトリルートの.husky/に配置する必要があります。package.jsonがサブディレクトリにある場合は、prepareスクリプトを調整します。

{
  "scripts": {
    "prepare": "cd .. && husky ./frontend/.husky"
  }
}

まとめ

huskyは、Gitフックをチーム全体で共有・強制するためのデファクトスタンダードなツールです。v9ではnpx husky init一発で初期化でき、.husky/ディレクトリにシェルスクリプトを置くだけというシンプルな設計になりました。lint-stagedやcommitlintと組み合わせることで、コード品質とコミット規約を自動的に担保する開発フローを簡単に構築できます。