Live
Black Hat USADark ReadingBlack Hat AsiaAI Businesstrunk/06cee8b2f9c6b2c10076efb3082adb7c2605a98c: [vllm hash update] update the pinned vllm hash (#179531)PyTorch ReleasesAI startup Rocket offers vibe McKinsey-style reports at a fraction of the costTechCrunch AIChatGPT Now Crawls 3.6x More Than Googlebot: What 24M Requests Reveal - Search Engine JournalGoogle News: ChatGPTYour Claude Code is Starving, the Food’s Scattered All Over Your Org, and Some of it is StaleTowards AItrunk/5e79c7376a212f6abc628dc596ddec1fcf67e1cb: Update third_party/kineto submodule to 4826a43 (#179492)PyTorch ReleasesMistral Introduces "Voxtral TTS": An Open-Weight Text-to-Voice Model Capable Of Cloning Any Voice From 3 Seconds Of Audio, Runs In 9 Languages, & Beats Elevenlabs Flash V2.5 With A 68.4% Human Preference Win Rate.Reddit r/LocalLLaMAAI chatbots programmed to validate users relying on mental health advice, experts warn - FOX 10 PhoenixGNews AI mental healthThe Agentic AI: How Autonomous AI Systems Are Rewriting the Rules of Work, Business, and TechnologyTowards AI[R] Agentic AI and Occupational Displacement: A Multi-Regional Task Exposure Analysis (236 occupations, 5 US metros)Reddit r/MachineLearningBefore Word2Vec: The Strange, Fascinating Road from Counting Words to Learning MeaningTowards AIAI Agents Are Calling Restaurants. Restaurants Can’t Talk Back.Towards AIThe Claude Code Leak Didn’t Hurt Cursor. It Forced a More Honest Competition.Towards AIBlack Hat USADark ReadingBlack Hat AsiaAI Businesstrunk/06cee8b2f9c6b2c10076efb3082adb7c2605a98c: [vllm hash update] update the pinned vllm hash (#179531)PyTorch ReleasesAI startup Rocket offers vibe McKinsey-style reports at a fraction of the costTechCrunch AIChatGPT Now Crawls 3.6x More Than Googlebot: What 24M Requests Reveal - Search Engine JournalGoogle News: ChatGPTYour Claude Code is Starving, the Food’s Scattered All Over Your Org, and Some of it is StaleTowards AItrunk/5e79c7376a212f6abc628dc596ddec1fcf67e1cb: Update third_party/kineto submodule to 4826a43 (#179492)PyTorch ReleasesMistral Introduces "Voxtral TTS": An Open-Weight Text-to-Voice Model Capable Of Cloning Any Voice From 3 Seconds Of Audio, Runs In 9 Languages, & Beats Elevenlabs Flash V2.5 With A 68.4% Human Preference Win Rate.Reddit r/LocalLLaMAAI chatbots programmed to validate users relying on mental health advice, experts warn - FOX 10 PhoenixGNews AI mental healthThe Agentic AI: How Autonomous AI Systems Are Rewriting the Rules of Work, Business, and TechnologyTowards AI[R] Agentic AI and Occupational Displacement: A Multi-Regional Task Exposure Analysis (236 occupations, 5 US metros)Reddit r/MachineLearningBefore Word2Vec: The Strange, Fascinating Road from Counting Words to Learning MeaningTowards AIAI Agents Are Calling Restaurants. Restaurants Can’t Talk Back.Towards AIThe Claude Code Leak Didn’t Hurt Cursor. It Forced a More Honest Competition.Towards AI
AI NEWS HUBbyEIGENVECTOREigenvector

Claude Code Hooks: How to Auto-Format, Lint, and Test on Every Save

Dev.to AIby gentic newsApril 5, 20264 min read2 views
Source Quiz

Configure hooks in .claude/settings.json to run prettier, eslint, and tests automatically, ensuring clean code without manual intervention. Claude Code Hooks: How to Auto-Format, Lint, and Test on Every Save Claude Code hooks are your automation layer for agentic development. They let you run shell commands at specific points in Claude's workflow—before tools run, after files are written, or when sessions end. Most developers discover hooks when they're tired of Claude writing code that doesn't match their formatter settings. Here's how to stop that permanently. Where Hooks Live Hooks go in your CLAUDE.md or in .claude/settings.json at the project root: { "hooks" : { "afterFileWrite" : "prettier --write $FILE" , "afterSessionEnd" : "npm test -- --passWithNoTests" } } The $FILE variable con

Configure hooks in .claude/settings.json to run prettier, eslint, and tests automatically, ensuring clean code without manual intervention.

Claude Code Hooks: How to Auto-Format, Lint, and Test on Every Save

Claude Code hooks are your automation layer for agentic development. They let you run shell commands at specific points in Claude's workflow—before tools run, after files are written, or when sessions end. Most developers discover hooks when they're tired of Claude writing code that doesn't match their formatter settings. Here's how to stop that permanently.

Where Hooks Live

Hooks go in your CLAUDE.md or in .claude/settings.json at the project root:

{  "hooks": {  "afterFileWrite": "prettier --write $FILE",  "afterSessionEnd": "npm test -- --passWithNoTests"  } }

Enter fullscreen mode

Exit fullscreen mode

The $FILE variable contains the path of the file Claude just wrote. $SESSION_ID is also available for session-based logging.

The Four Hook Points You Need to Know

Hook When it fires Common use

beforeToolRun Before any tool executes Log what Claude is about to do

afterFileWrite After Claude writes or edits a file Format, lint, type-check

afterBashRun After a bash command completes Capture output, trigger CI

afterSessionEnd When the session closes Run test suite, commit

Auto-Format on Write (The Essential Hook)

This is the most common hook. Claude writes a file → it gets formatted immediately:

{  "hooks": {  "afterFileWrite": "npx prettier --write $FILE 2>/dev/null || true"  } }

Enter fullscreen mode

Exit fullscreen mode

The || true prevents Claude from seeing a non-zero exit code as an error. If the file isn't JS/TS/CSS, prettier skips it silently.

Chain Linting with Formatting

You can only have one afterFileWrite hook per settings block. Chain multiple commands with ; or &&:

{  "hooks": {  "afterFileWrite": "npx prettier --write $FILE 2>/dev/null; npx eslint --fix $FILE 2>/dev/null; true"  } }

Enter fullscreen mode

Exit fullscreen mode

This runs prettier first, then eslint with auto-fix. The final true ensures the hook always exits with code 0.

Auto-Test After Session

Run your test suite every time Claude finishes a session:

{  "hooks": {  "afterSessionEnd": "npm test -- --passWithNoTests 2>&1 | tail -20"  } }

Enter fullscreen mode

Exit fullscreen mode

Claude sees the test output and can immediately fix failures in the next session. The tail -20 shows just the last 20 lines of output to avoid overwhelming the context window.

The Self-Healing Loop Pattern

This is where hooks get powerful. Combine afterSessionEnd with a script that reruns Claude if tests fail:

#!/bin/bash

run-with-tests.sh

npm test 2>&1 > /tmp/test-output.txt if [ $? -ne 0 ]; then echo "Tests failed, asking Claude to fix..." claude --print "Fix the failing tests. Output:\n$(cat /tmp/test-output.txt)"
--allowedTools Edit,Bash fi`

Enter fullscreen mode

Exit fullscreen mode

Then set:

{  "hooks": {  "afterSessionEnd": "./run-with-tests.sh"  } }

Enter fullscreen mode

Exit fullscreen mode

This creates a loop: Claude writes code → session ends → tests run → if red, Claude is called again with failure output → it fixes → tests run again. The loop continues until green.

Watch Out for Rate Limits

The self-healing loop is great until Claude hits its hourly rate limit mid-loop. When that happens, the loop stalls and your terminal hangs. One workaround mentioned in the community is using a proxy service like SimplyLouie ($2/month) that removes rate limits:

export ANTHROPIC_BASE_URL=https://simplylouie.com/api/proxy npm run claude-loop

Enter fullscreen mode

Exit fullscreen mode

Audit What Claude Does

If you want a log of every tool Claude runs:

{  "hooks": {  "beforeToolRun": "echo \"$(date): $TOOL_NAME $TOOL_INPUT\" >> ~/.claude-audit.log"  } }

Enter fullscreen mode

Exit fullscreen mode

This creates an append-only audit log at ~/.claude-audit.log. Useful for understanding what Claude actually does in long sessions.

Hooks vs CLAUDE.md: They Work Best Together

Hooks handle behavior (what happens after actions). CLAUDE.md handles knowledge (what Claude should know and follow).

They work best together:

  • CLAUDE.md: "Always use Prettier for formatting, never manual spaces"

  • Hook: afterFileWrite: prettier --write $FILE

CLAUDE.md tells Claude the rule. The hook enforces it automatically even if Claude forgets.

Start Here

Begin with the formatter hook. Once you've run a session without manually formatting a single file, add linting. Then testing. The combination creates a development environment where Claude's output is always clean, linted, and tested—without you lifting a finger.

Originally published on gentic.news

Was this article helpful?

Sign in to highlight and annotate this article

AI
Ask AI about this article
Powered by Eigenvector · full article context loaded
Ready

Conversation starters

Ask anything about this article…

Daily AI Digest

Get the top 5 AI stories delivered to your inbox every morning.

More about

claudeavailableservice

Knowledge Map

Knowledge Map
TopicsEntitiesSource
Claude Code…claudeavailableserviceagenticagentclaude codeDev.to AI

Connected Articles — Knowledge Graph

This article is connected to other articles through shared AI topics and tags.

Knowledge Graph100 articles · 275 connections
Scroll to zoom · drag to pan · click to open

Discussion

Sign in to join the discussion

No comments yet — be the first to share your thoughts!

More in Products