Claude Codeを使っていて、こんなことを思ったことはありませんか。
- ファイルを保存するたびに手動でフォーマッター(コードの見た目を自動で整えるツール)を実行するのが面倒
rm -rfやgit push --forceみたいな危険なコマンドをうっかり実行しそうで怖い- コミット(変更の記録)するたびにコードチェックツールを手動で実行するのを忘れてしまう
こういう「毎回やらなきゃいけないけど、つい忘れちゃう作業」を自動化してくれるのが**Hooks(フック)**です。Claude Codeが特定の操作をするたびに、あらかじめ設定しておいたコマンドが自動で実行される仕組みです。つまり、「AIがファイルを保存したら、自動的にコードを整形する」といったことが設定一つでできるようになります。
この記事では、Hooksの基本的な考え方から設定のやり方、すぐに使えるレシピまでを、できるだけわかりやすく説明します。設定の書式は2026年8月時点の公式ドキュメント(Claude Code Hooks リファレンス)に合わせています。
Hooksとは何か
Hooksは、Claude Codeの作業の流れの中で、決まったタイミングに自動で実行されるコマンドのことです。
Claude Code
がファイルを保存
Hook発動!
Prettierが自動実行
整形されたキレイな
ファイルが保存される
ここで大事なポイントは、HooksはAI(LLM)に頼らず、確実に毎回同じように動く処理を差し込めるということです。AIは「うっかり忘れる」こともありますが、Hooksなら絶対に忘れません。つまり、「AIが忘れるかもしれない定型作業を自動化するのに最適」な仕組みです。
同じ「AIに決まった動きをさせる」でも、CLAUDE.mdがAIへのお願いなのに対し、Hooksは強制力のある処理です。守ってほしいルールがお願いベースで破られるなら、Hooksに移すのが正解です。
よく使うタイミング
「いつ自動実行するか」を選べます。日常的に使うのは次の7つです。
| タイミング | いつ発動する? | こんなことに使える |
|---|---|---|
| SessionStart | セッション(作業の会話)が始まったとき | 環境チェック、必要なパーツがそろっているか確認 |
| PreToolUse | AIがツールを実行する直前 | 危険なコマンドをブロックする、入力チェック |
| PostToolUse | AIがツールを実行した直後 | コードの自動整形、コードチェックの実行 |
| PostToolUseFailure | AIのツール実行が失敗したとき | エラーの記録、復旧処理 |
| UserPromptSubmit | ユーザーが指示を送信したとき | 指示内容のチェック、追加情報の差し込み |
| Stop | AIが応答を終えたとき | 完了通知、作業のまとめ |
| SessionEnd | セッションが終わるとき | 後片付け、レポートの出力 |
タイミングは他にもある
公式にはこの他にも PermissionRequest(権限を求めたとき)・PreCompact(履歴の圧縮前)・SubagentStop(サブエージェント終了時)・FileChanged(ファイル変更時)など多数のイベントがあります。まずは上の7つで足ります。全一覧は公式ドキュメントで確認してください。
設定のやり方
Hooksは .claude/settings.json というファイルに書きます。つまり、プロジェクトのフォルダの中に .claude というフォルダを作って、その中に settings.json を置くということです(自分の全プロジェクトで共通にしたいなら ~/.claude/settings.json)。
基本的な書き方
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs -r npx prettier --write"
}
]
}
]
}
}
この設定だと、Claude Codeがファイルを書き込む(Write)か編集する(Edit)たびに、Prettier(コード整形ツール)が自動実行されます。
ここが一番間違えやすい部分です。 イベント名の下は「マッチャーの配列」で、そのさらに中に "hooks" という配列があり、実際に動かすコマンドはそこに入れます。この二段構えを省いて matcher と command を同じ階層に並べても動きません。
設定のポイント
| 項目 | どういう意味? | 書き方の例 |
|---|---|---|
matcher | どのツールのときに発動するか(正規表現で指定) | "Write|Edit"(書き込みか編集のとき), "Bash"(コマンド実行のとき) |
type | ハンドラの種類。シェルコマンドなら command | "command" |
command | 発動したら何を実行するか | "npm test" |
timeout | 打ち切りまでの秒数(既定600秒) | 30 |
値の受け取り方(環境変数ではない)
Hookのコマンドには、発動時の情報がJSONで標準入力(stdin)から渡されます。シェル変数として用意されているわけではないので、jq などで取り出します。
# ファイルパスを取り出す
jq -r '.tool_input.file_path'
# 実行されようとしているBashコマンドを取り出す
jq -r '.tool_input.command'
主なフィールドは次の通りです。
| フィールド | 何が入る? |
|---|---|
.tool_name | 実行されたツールの名前(Bash Write など) |
.tool_input | ツールに渡された内容(.file_path .command など) |
.cwd | 作業中のフォルダ |
.session_id | セッションの識別子 |
なお、コマンド文字列の中では ${CLAUDE_PROJECT_DIR}(プロジェクトの場所)が使えます。スクリプトファイルを呼び出すときはこれで絶対パスを指定します。
動作を止める=終了コード2
Hookで「この操作をやめさせたい」ときは、終了コード2で終わります。標準エラー出力に書いたメッセージが、そのままAIに理由として渡ります。
echo "この操作はブロックしました" >&2
exit 2
終了コード0は「そのまま進めてよい」、1は「Hook自体のエラー(操作はブロックされない)」です。ブロックのつもりで exit 1 と書くと止まりません。
すぐに使えるレシピ10選
レシピ1: ファイル保存時に自動でコードを整形する
一番基本的で、一番効果が高いHookです。Claude Codeがファイルを保存するたびに、Prettier(コード整形ツール)が自動で走ります。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs -r npx prettier --write 2>/dev/null || true"
}
]
}
]
}
}
末尾の 2>/dev/null || true は「Prettierが対応していないファイル形式だったときにエラーで止まらないようにする」おまじないです。これがないと、対応外のファイルを保存したときにエラーが出て作業が止まってしまうことがあります。
レシピ2: 危険なコマンドをブロックする
rm -rf /(ファイルを全部消す超危険コマンド)や git push --force(変更を強制的に上書きする危険な操作)のような、うっかり実行すると取り返しのつかないコマンドを事前にブロックします。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "cmd=$(jq -r '.tool_input.command'); case \"$cmd\" in *'rm -rf /'*|*'push --force'*|*'DROP TABLE'*|*'DROP DATABASE'*) echo 'BLOCKED: 危険なコマンドです' >&2; exit 2;; esac"
}
]
}
]
}
}
PreToolUseは軽い処理だけにしよう
PreToolUse(ツール実行の直前)のHookはAIが何かするたびに毎回呼ばれるので、重い処理を入れると全体が遅くなります。ここにはシンプルなチェックだけ入れましょう。
レシピ3: TypeScriptの型チェックを自動実行する
TypeScriptファイルが変更されるたびに、型チェック(書き方が正しいかの確認)を自動で実行します。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "f=$(jq -r '.tool_input.file_path'); case \"$f\" in *.ts|*.tsx) npx tsc --noEmit 2>&1 | head -20;; esac; true"
}
]
}
]
}
}
レシピ4: ESLint(コード品質チェックツール)を自動実行する
ファイル保存後にESLintでコードの品質をチェックし、自動で直せるものは直してくれます。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "f=$(jq -r '.tool_input.file_path'); case \"$f\" in *.js|*.jsx|*.ts|*.tsx) npx eslint \"$f\" --fix 2>/dev/null;; esac; true"
}
]
}
]
}
}
レシピ5: セッション開始時に環境を確認する
セッションが始まったときに、Node.jsのバージョンや必要なパーツがちゃんとそろっているかを自動で確認します。つまり、「作業を始める前に、準備が整っているか自動でチェックする」ということです。
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "echo '=== Environment ===' && node -v && npm ls --depth=0 2>/dev/null | tail -5"
}
]
}
]
}
}
SessionStart のように特定のツールに紐づかないイベントでは、matcher を省けます。
レシピ6: 大事なファイルの編集をブロックする
設定ファイルやロックファイルなど、「このファイルは勝手に触ってほしくない」というファイルの編集をブロックします。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "f=$(jq -r '.tool_input.file_path'); case \"$f\" in *package-lock.json|*.env|*/prisma/migrations/*) echo 'BLOCKED: 保護ファイルです' >&2; exit 2;; esac"
}
]
}
]
}
}
レシピ7: コミット前にテストを自動実行する
git commit(変更の記録)をする前に、自動でテストを実行してくれます。テストが落ちたらコミット自体を止めます。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "cmd=$(jq -r '.tool_input.command'); case \"$cmd\" in *'git commit'*) npm test >/tmp/test.log 2>&1 || { echo 'BLOCKED: テストが失敗しています' >&2; tail -10 /tmp/test.log >&2; exit 2; };; esac; true"
}
]
}
]
}
}
レシピ8: ファイルが大きくなりすぎたら警告する
AIが極端に大きなファイルを作ってしまうのを防ぎます。500行を超えたら警告を出します。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "f=$(jq -r '.tool_input.file_path'); [ -f \"$f\" ] && [ \"$(wc -l < \"$f\")\" -gt 500 ] && echo \"WARNING: $f は500行を超えています\"; true"
}
]
}
]
}
}
レシピ9: 画像ファイルの最適化をリマインドする
画像ファイルが追加されたときに、「最適化したほうがいいよ」とリマインドしてくれます。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "cmd=$(jq -r '.tool_input.command'); case \"$cmd\" in *.png*|*.jpg*|*.jpeg*) echo 'TIP: sharp や squoosh で画像を圧縮しましょう';; esac; true"
}
]
}
]
}
}
レシピ10: セッション終了時に作業のまとめを出す
セッションが終わるときに、どのファイルが変更されたかをログに記録します。つまり、「今日の作業記録を自動で残す」ということです。
{
"hooks": {
"SessionEnd": [
{
"hooks": [
{
"type": "command",
"command": "{ date; git diff --stat 2>/dev/null; } >> ~/.claude/session-log.txt"
}
]
}
]
}
}
複数のHookを組み合わせて使う
実際のプロジェクトでは、いくつかのHookを組み合わせて使うのがふつうです。以下は「セッション開始時の環境チェック」「危険なコマンドのブロック」「大事なファイルの保護」「自動コード整形」を全部まとめた設定例です。
{
"hooks": {
"SessionStart": [
{
"hooks": [
{ "type": "command", "command": "node -v && npm ls --depth=0 2>/dev/null | tail -3" }
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "cmd=$(jq -r '.tool_input.command'); case \"$cmd\" in *'rm -rf'*|*'--force'*|*'DROP '*) echo 'BLOCKED' >&2; exit 2;; esac"
}
]
},
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "f=$(jq -r '.tool_input.file_path'); case \"$f\" in *.env|*package-lock.json) echo 'BLOCKED' >&2; exit 2;; esac"
}
]
}
],
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs -r npx prettier --write 2>/dev/null || true"
}
]
}
]
}
}
同じイベントの下にマッチャーを複数並べられます。上の例では PreToolUse に「Bash向け」と「Write/Edit向け」を分けて置いています。
Hooksを使うときの注意点
無限ループに気をつけよう
「Hookがファイルを書き込む → その書き込みでまたHookが発動する → またファイルを書き込む…」という無限ループが起きる可能性があります。Hookのコマンドではファイルの書き込みを避けるか、発動条件をちゃんと絞っておきましょう。
重い処理はPreToolUseに入れない
特にPreToolUseのHookは、AIが何かするたびに毎回実行されます。ここにテストの全件実行みたいな重い処理を入れると、作業全体がすごく遅くなります。重い処理はPostToolUse(作業の後)に置くか、timeout を短く設定しておきましょう。
意図しないブロックを避ける
チェック処理が想定外の理由で終了コード2を返すと、AIの作業が止まります。ブロックしたい条件に当てはまらないときは必ず正常終了するように、レシピのように末尾へ true を置いておくのが安全です。
まずは1つから始めよう
最初からたくさんのHookを設定しようとすると、何が問題を起こしているかわからなくなります。まず1つ(自動コード整形)だけ入れて、ちゃんと動くのを確認してから、少しずつ追加していくのがおすすめです。設定を反映するには、Claude Codeを起動し直してください。
まず入れるべきHookはこの2つ
迷ったら「PostToolUseの自動コード整形(レシピ1)」と「PreToolUseの危険コマンドブロック(レシピ2)」の2つだけ入れましょう。これだけで開発の安全性とコード品質がぐっと上がります。
よくある質問
Q. 設定を書いたのに何も起きません。
A. まず疑うのは入れ子の書き方です。イベント名 → マッチャーの配列 → その中の "hooks" 配列 → {"type": "command", "command": "..."} という二段構えになっているか確認してください。matcher と command を同じ階層に並べる書き方は動きません。次に、Claude Codeを起動し直したかを確認します。
Q. $CLAUDE_FILE_PATH のような変数は使えますか?
A. 使えません。ファイルパスやコマンドは標準入力のJSONで渡ってくるので、jq -r '.tool_input.file_path' のように取り出します。コマンド文字列の中で置き換わるのは ${CLAUDE_PROJECT_DIR} などのパス系だけです。
Q. ブロックしたいのに操作が実行されてしまいます。
A. 終了コードが1になっている可能性が高いです。ブロックは終了コード2です。理由は標準エラー出力(>&2)に書くとAIに伝わります。
Q. Hooksと CLAUDE.md はどう使い分けますか?
A. CLAUDE.mdの書き方はAIへの「お願い」で、状況によっては守られません。Hooksは機械的に必ず実行される処理です。守られないと困るルール(整形・保護・ブロック)はHooksへ、方針や書き方の好みはCLAUDE.mdへ、が基本です。記憶の仕組み全体はClaude Codeのメモリ機能にまとめています。
Q. チームで共有できますか?
A. できます。.claude/settings.json をリポジトリにコミットすれば全員に効きます。自分だけの設定にしたいときは ~/.claude/settings.json に書きます。
Q. 動作が重くなったときはどうしますか?
A. PreToolUseに置いた処理をPostToolUseへ移すか、timeout を短くします。日々の速度改善はClaude Code実践Tips15選も参考になります。
Q. どの業務からAI自動化を始めるべきですか?
A. Hooksは開発の現場向けの仕組みです。事務や経理から入りたい場合はAIで業務効率化する方法まとめで目的別のルートを確認してください。
まとめ
Hooksは、Claude Codeの作業の流れに対して**「絶対に忘れない自動処理」を差し込む仕組み**です。AIが忘れるかもしれないことも、Hooksなら毎回確実に実行してくれます。
今日から始めるステップ:
.claude/settings.jsonを作る- まず自動コード整形(レシピ1)を設定して、ちゃんと動くか確認
- 危険コマンドブロック(レシピ2)を追加する
- プロジェクトに合わせて、必要なHookを少しずつ追加
- ときどき設定を見直して、使わなくなったHookは消す
Hooksをうまく設定すれば、「コードの整形を忘れた」「危険なコマンドを実行してしまった」という事故がゼロになり、コードの品質を自動で守れるようになります。
情報の時点
本記事の設定書式・イベント名・終了コードの扱いは 2026年8月11日時点の公式ドキュメントに基づいています。Claude Codeは更新が速いため、動かない場合は公式リファレンスで最新の書式を確認してください。