CLAUDE LABJP
FORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as OctoberFORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as October
Articles/Claude Code
Claude Code/2026-05-07Intermediate

Pre-commit AI Review with Claude Code, husky, and lint-staged — Reviewing Only Staged Files

A pragmatic guide to running a lightweight Claude Code review on only the files you've staged for commit. Using husky and lint-staged, this setup minimizes both cost and latency for solo developers.

claude-code129huskylint-stagedpre-commitcode-review5automation95

A few months ago, while building a small app, I noticed that asking Claude Code to review my code on every save was both expensive and disruptive to my flow. Manually typing /review was reliable but easy to forget. After thinking it over, I realized the right moment was the one I was already pausing to review my work: the moment of git commit. And the right scope wasn't the whole repo — only what I was about to commit.

That led me to combine husky and lint-staged with Claude Code so that only staged files would be passed to a quick AI review. The result was quieter and more useful than I expected, and this article walks through the exact setup from a solo developer's point of view.

Why "staged files only" is the right scope

Claude Code is happy to read the entire repository, but doing that on every commit chops your rhythm into pieces. What I noticed in practice is that when you give it only the files you're about to commit, the feedback becomes sharper, not weaker.

The reason is simple. With git diff --cached you're handing Claude exactly the change you're proposing — nothing more, nothing less. It stops reaching for "general advice" and starts asking the right question: does this change make sense, by itself, right now?

There's a practical reason too: lint-staged's design — passing the staged file paths as command-line arguments — fits beautifully with Claude Code's --print (non-interactive) mode. You get a clean shell pipeline that scales to any number of changed files.

Prerequisites and the big picture

Before we begin, make sure your environment has:

  • Node.js 20 or later (required by husky v9)
  • The claude CLI on your PATH (claude --version should return cleanly)
  • A repository with a package.json

The setup itself is small:

  1. Initialize husky and create .husky/pre-commit
  2. Install lint-staged and configure which file globs trigger which task
  3. Have lint-staged invoke a tiny shell script that hands staged files to Claude Code
  4. Exit non-zero from the script if Claude raises any concern, blocking the commit

Step 1: Set up husky and lint-staged

Install both as dev dependencies:

# Run from the project root
npm install --save-dev husky lint-staged
 
# Initialize husky v9 (creates .husky/)
npx husky init

npx husky init writes a starter .husky/pre-commit:

# Default content
npm test

Replace it with npx lint-staged:

# .husky/pre-commit
npx lint-staged

Then add the lint-staged config to package.json:

{
  "lint-staged": {
    "*.{ts,tsx,js,jsx}": [
      "scripts/claude-staged-review.sh"
    ]
  }
}

The trick here is keeping the glob narrow. In my own project I deliberately exclude Markdown and config files. When the review target gets too wide, Claude has too many genres of files to reason about and the feedback dilutes.

Step 2: Write the review script

Create scripts/claude-staged-review.sh:

#!/usr/bin/env bash
# scripts/claude-staged-review.sh
# lint-staged passes staged file paths as positional arguments
set -euo pipefail
 
FILES=("$@")
 
if [ ${#FILES[@]} -eq 0 ]; then
  echo "ℹ️ No files to review. Skipping."
  exit 0
fi
 
# Prompt body sent to Claude
PROMPT=$(cat <<'PROMPT_EOF'
Below is a diff of files staged for the next git commit.
Act as a code reviewer and check ONLY these four points:
 
1. Obvious bugs, null safety, or type mismatches
2. Changes that need tests but have none added
3. Accidentally committed secrets (API keys, tokens, PII)
4. Serious naming or separation-of-concerns issues
 
If everything looks fine, output exactly "OK" on the first line.
If there are concerns, list them as terse bullet points.
Do NOT suggest refactors or general improvements.
PROMPT_EOF
)
 
# Get the staged diff for the changed files only
DIFF=$(git diff --cached -- "${FILES[@]}")
 
# Run Claude Code in non-interactive mode
RESULT=$(printf '%s\n\n```diff\n%s\n```\n' "$PROMPT" "$DIFF" | claude --print --model claude-haiku-4-5)
 
echo "$RESULT"
 
# If the first line is anything other than "OK", abort the commit
if [ "$(echo "$RESULT" | head -n1 | tr -d '[:space:]')" = "OK" ]; then
  exit 0
else
  echo ""
  echo "❌ Claude flagged concerns. Fix them and commit again."
  echo "💡 To bypass temporarily: git commit --no-verify"
  exit 1
fi

Don't forget to make it executable:

chmod +x scripts/claude-staged-review.sh

A few decisions in this script are worth explaining.

I'm calling claude --print --model claude-haiku-4-5 because pre-commit only earns its keep if it's fast. Sonnet and Opus catch slightly more, but the wait time will eventually push you to skip the hook entirely. With Haiku 4.5, I get a hit on the obvious-bug-or-secret category in roughly the time it takes me to type a commit message.

The prompt explicitly says "no refactor suggestions." Claude is naturally helpful — left alone, it will offer renames, decompositions, and design ideas. All good in code review, all distracting at commit time. Setting the boundary upfront removes that noise.

The exit logic checks "first line equals OK" rather than scanning the whole response. Claude sometimes writes "OK. Looks fine." or "OK." — both pass, which is what you want.

Step 3: Try it out

Make a trivial change and commit:

echo "console.log('test')" >> src/example.ts
git add src/example.ts
git commit -m "test pre-commit"

You should see something like:

✔ Backed up original state in git stash
✔ Running tasks for staged files...
ℹ️ No files to review. Skipping.
✔ Applying modifications from tasks...
[main abc1234] test pre-commit

Now intentionally introduce a problem:

// src/example.ts
const apiKey = "sk-ant-api03-XXXXXXXXXXXXX"; // accidentally committed real token
console.log(apiKey);

Claude will stop you:

- src/example.ts contains what looks like a real Anthropic API key.
  Remove it and load the value from an environment variable.
- Rotate the key in your console — it may already be exposed.

❌ Claude flagged concerns. Fix them and commit again.
💡 To bypass temporarily: git commit --no-verify

That moment — the "oh no, I would have pushed that" moment — is the entire point of this setup. Without breaking your normal git flow, you get one extra pair of eyes at the right time.

What I learned running this in real projects

My first version was extravagant: every staged file, full Sonnet review, broad prompt. After three commits I was already using --no-verify by reflex. The hook was technically working but I had stopped trusting it.

Trimming it down to "staged files only, Haiku 4.5, four explicit checks" brought the average run time to four to six seconds. That's about how long it takes to write a half-decent commit message, so the friction disappears entirely.

The lesson, for me, was that the goal isn't to push Claude to its limit. It's to make Claude small enough to live inside the rhythm I already have.

Tuning knobs

Vary the prompt by file type

You can branch on ${FILES[@]} and use different prompts for tests vs. production code:

# Crude example: detect test files
if [[ "${FILES[0]}" =~ \.test\. ]]; then
  PROMPT="$PROMPT_TEST"
else
  PROMPT="$PROMPT_PROD"
fi

That said, I'd be cautious about getting clever here. Pre-commit scripts are easier to live with when they're boring and obvious.

Cost in practice

A typical 5–10 file commit reviewed by Haiku 4.5 lands at a small fraction of a cent. Even at 30 commits per day, my own bills stay around a dollar or two per month for a small project.

If you want to trim further, exclude *.test.* from the lint-staged glob, or drop docs/ from the review path entirely.

Conditional escalation to Sonnet

For larger changes (refactors, new features), you can route to Sonnet based on diff size:

LINES=$(echo "$DIFF" | wc -l)
if [ "$LINES" -gt 200 ]; then
  MODEL="claude-sonnet-4-6"
else
  MODEL="claude-haiku-4-5"
fi
RESULT=$(printf '...' | claude --print --model "$MODEL")

Diffs over 200 lines get the more thoughtful model; smaller changes stay fast.

How this compares to similar approaches

Before settling on this setup I considered a couple of alternatives.

Claude Code's own Hooks (PreToolUse, PostToolUse, etc.) react to tool calls inside a Claude Code session. They're powerful — see the Claude Code Hooks Master Guide — but they don't fire on git events, so they don't fit this use case.

GitHub Actions PR review is the obvious cloud counterpart. It works well, but the feedback arrives a minute or two after pushing, which is too late for the "catch it before it leaves the laptop" goal of this article. The two approaches are complementary: a fast local pre-commit catches obvious issues, then a deeper PR review handles design-level concerns.

If you want to dig into claude --print itself, the headless automation guide for --bare and --print covers the underlying mode.

Troubleshooting

claude command not found

husky hooks run in a non-login shell, so your usual PATH may not be loaded.

# Add this near the top of .husky/pre-commit
export PATH="$HOME/.local/bin:/opt/homebrew/bin:$PATH"
npx lint-staged

That covers most cases.

lint-staged says "no staged files matched"

This just means the staged files don't match your glob. A Markdown-only commit, for example, won't trigger *.{ts,tsx,js,jsx}. That's expected behavior — nothing is broken.

Bypassing the hook for hotfixes

When you genuinely need to skip review:

git commit --no-verify -m "hotfix: rollback"

If you find yourself reaching for --no-verify often, take that as a signal to narrow the prompt further, not to disable the hook.

A starting point

Start with *.{ts,tsx,js,jsx} on a small project. Copy the script as-is, change one file, and commit. The first run tells you immediately whether your PATH and CLI access are wired correctly.

Once it's running, you'll notice that Claude Code stops feeling like a heavy reviewer you have to invoke and starts feeling like a quiet partner standing next to you at commit time. In my own work, this setup has caught two accidental key commits that would have been painful to recover from.

Thanks for reading. If you've been looking for a way to add an AI review step to your local workflow without slowing yourself down, I hope this helps you get there.

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Claude Code2026-03-26
Fully Automated Code Review with Claude Code—Implementing Harness Engineering Patterns
Master harness engineering (coined by HashiCorp founder) for AI-driven code review. Learn Claude Code implementation patterns and solutions for over-suggestion and review oscillation.
Claude Code2026-07-17
The Morning My Table Ended in "… 2,847 more rows" — Separating Render Caps from Token Cost in Tool Output
Claude Code 2.1.209 caps markdown tables at 200 rows plus a remainder count. Only the rendering is capped — the model still receives every row. Here is how to measure the gap and redesign tool output around aggregates.
Claude Code2026-07-15
Answering auto mode's confirmation prompts in headless runs — a deny-by-default permission-prompt-tool
auto mode's confirmation step is a friend when you're at the keyboard, but in an unattended midnight run it becomes the reason a job sits waiting until morning. Here is how I catch those prompts with permission-prompt-tool, decide deny-by-default, and log every ruling — with working code.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →