Skip to content

Script Automation

Script automation transforms Claude Code from an interactive assistant into a powerful automation engine. By combining hooks, custom commands, headless mode, and scripting patterns, you can automate everything from code formatting to large-scale migrations. This guide reveals how to build automation workflows that run autonomously while maintaining the flexibility to intervene when needed.

Hooks are Claude Code’s secret weapon for automation. They’re shell commands that execute automatically at specific points in Claude’s lifecycle, turning repetitive manual tasks into seamless background operations.

Hook Events

The hook system provides five strategic intervention points:

  • PreToolUse: Before Claude executes any tool/command
  • PostToolUse: After a tool/command successfully completes
  • UserPromptSubmit: When you submit a prompt to Claude
  • Notification: When Claude sends a notification
  • Stop: When Claude finishes its response

Let’s start with the most common automation: automatic code formatting.

  1. Create the hooks configuration

    Terminal window
    mkdir -p .claude
  2. Add to .claude/settings.json

    {
    "hooks": [
    {
    "matcher": "Edit|Write",
    "hooks": [
    {
    "type": "command",
    "command": "prettier --write \"$CLAUDE_FILE_PATHS\""
    }
    ]
    }
    ]
    }
  3. Test the hook

    Terminal window
    # Ask Claude to create a messy JavaScript file
    claude "Create a test.js file with unformatted code"
    # The file will be automatically formatted after creation!
{
"hooks": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "if [[ \"$CLAUDE_FILE_PATHS\" =~ \\.(ts|tsx)$ ]]; then npx prettier --write \"$CLAUDE_FILE_PATHS\"; elif [[ \"$CLAUDE_FILE_PATHS\" =~ \\.py$ ]]; then black \"$CLAUDE_FILE_PATHS\"; elif [[ \"$CLAUDE_FILE_PATHS\" =~ \\.go$ ]]; then gofmt -w \"$CLAUDE_FILE_PATHS\"; fi"
}
]
}
]
}

Hooks receive rich context through environment variables:

Terminal window
# Available in all hooks
$CLAUDE_FILE_PATHS # Space-separated list of affected files
$CLAUDE_SESSION_ID # Unique session identifier
$CLAUDE_TOOL_NAME # Name of the tool being executed
$CLAUDE_USER_PROMPT # The original user prompt
# JSON payload via stdin
{
"hookEventName": "PostToolUse",
"sessionId": "uuid-here",
"toolName": "Edit",
"filePaths": ["src/index.ts"],
"result": "success"
}

Custom slash commands turn complex automation workflows into simple, parameterized commands. They’re stored as Markdown files and can be shared across your team.

  1. Create the commands directory

    Terminal window
    mkdir -p .claude/commands
  2. Create your first command (.claude/commands/test.md)

    Please create comprehensive tests for: $ARGUMENTS
    Test requirements:
    - Use our standard testing framework
    - Include unit and integration tests
    - Mock external dependencies
    - Test error cases and edge conditions
    - Achieve at least 80% coverage
    - Place tests in __tests__ directory
    - Follow our naming convention: *.test.ts
  3. Use the command

    Terminal window
    claude
    > /test UserService
    # Claude generates comprehensive tests for UserService

Migration Command

.claude/commands/migrate.md
Migrate $ARGUMENTS from our old API to the new API:
1. Find all usages of the old API
2. Update imports to use new package
3. Transform method calls to new syntax
4. Update any type definitions
5. Run tests to verify migration
6. Create a migration report

Security Audit

.claude/commands/audit.md
Perform security audit on: $ARGUMENTS
- Check for SQL injection vulnerabilities
- Scan for XSS possibilities
- Review authentication flows
- Check for exposed secrets
- Verify input validation
- Generate security report

Performance Analysis

.claude/commands/perf.md
Analyze performance of: $ARGUMENTS
- Profile the code execution
- Identify bottlenecks
- Check for N+1 queries
- Review algorithm complexity
- Suggest optimizations
- Create benchmark tests

Documentation Generator

.claude/commands/doc.md
Generate documentation for: $ARGUMENTS
- Create comprehensive docstrings
- Generate API documentation
- Include usage examples
- Document edge cases
- Create markdown guides
- Update README if needed

For larger teams, organize commands hierarchically:

.claude/commands/
├── backend/
│ ├── migrate.md # /backend:migrate
│ ├── optimize.md # /backend:optimize
│ └── test.md # /backend:test
├── frontend/
│ ├── component.md # /frontend:component
│ ├── style.md # /frontend:style
│ └── test.md # /frontend:test
└── devops/
├── deploy.md # /devops:deploy
└── monitor.md # /devops:monitor

Headless mode enables Claude Code to run in non-interactive environments, perfect for CI/CD automation.

Terminal window
# Run a single command
claude -p "Fix all linting errors" --output-format stream-json
# With specific tools allowed
claude -p "Update dependencies" --allowedTools "Edit Bash(npm:*)"
# Verbose mode for debugging
claude -p "Run security audit" --verbose

Fanning Out Pattern

Use this pattern for processing many files independently:

migrate-components.sh
#!/bin/bash
# Generate task list
find src/components -name "*.jsx" > components.txt
# Process each component
while read -r file; do
echo "Migrating $file..."
claude -p "Convert $file from class component to functional component with hooks.
Return 'OK' if successful, 'FAIL' if not possible." \
--allowedTools "Edit Read" \
--output-format stream-json | jq -r '.status'
done < components.txt

Pipeline Pattern

Chain Claude Code with other tools:

Terminal window
# Analyze logs and send alerts
tail -f /var/log/app.log | \
claude -p "Monitor this log stream. If you see any errors or anomalies,
output a JSON object with severity and message" \
--output-format stream-json | \
jq -c 'select(.severity == "high")' | \
while read alert; do
# Send to alerting system
curl -X POST https://alerts.example.com/webhook \
-H "Content-Type: application/json" \
-d "$alert"
done

Run multiple Claude instances for massive parallelization:

parallel-refactor.sh
#!/bin/bash
# Create work directories
for i in {1..4}; do
git worktree add "../refactor-$i" "refactor-branch-$i"
done
# Launch parallel Claude instances
tmux new-session -d -s refactor-1 'cd ../refactor-1 && claude -p "Refactor authentication module"'
tmux new-session -d -s refactor-2 'cd ../refactor-2 && claude -p "Refactor user management"'
tmux new-session -d -s refactor-3 'cd ../refactor-3 && claude -p "Refactor payment processing"'
tmux new-session -d -s refactor-4 'cd ../refactor-4 && claude -p "Refactor notification system"'
# Monitor progress
watch -n 5 'tmux list-sessions'

Automate changes across multiple services:

update-api-version.sh
#!/bin/bash
services=("user-service" "order-service" "payment-service" "notification-service")
new_version="v2.0"
for service in "${services[@]}"; do
echo "Updating $service to API $new_version..."
cd "../$service" || continue
claude -p "Update this service to use API $new_version:
1. Update client library to $new_version
2. Modify all API calls to use new endpoints
3. Update request/response types
4. Run tests to verify
5. Commit with message: 'chore: update to API $new_version'
" --allowedTools all --dangerously-skip-permissions
# Push changes
git push origin "api-update-$new_version"
done
# Create PR for all services
gh pr create --title "Update all services to API $new_version" \
--body "Automated update of all services to use API $new_version"

Automate security and compliance checks:

{
"hooks": [
{
"matcher": "UserPromptSubmit",
"hooks": [
{
"type": "command",
"command": "./scripts/compliance-check.sh \"$CLAUDE_USER_PROMPT\""
}
]
},
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "./scripts/security-scan.sh \"$CLAUDE_FILE_PATHS\""
}
]
}
]
}

Automatically maintain documentation:

.claude/commands/release.md
Prepare release $ARGUMENTS:
1. Generate changelog from git commits
2. Update version numbers in all files
3. Generate API documentation
4. Update SDK documentation
5. Create migration guide if needed
6. Generate release notes
7. Create git tag
8. Build and test release artifacts
Use our standard templates and follow semantic versioning.

Track Claude Code usage for insights:

.claude/hooks/usage-tracker.sh
#!/bin/bash
# Log all tool usage
echo "{
\"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",
\"session_id\": \"$CLAUDE_SESSION_ID\",
\"tool\": \"$CLAUDE_TOOL_NAME\",
\"files\": \"$CLAUDE_FILE_PATHS\",
\"user\": \"$(whoami)\",
\"project\": \"$(basename $(pwd))\"
}" >> ~/.claude/usage.jsonl
# Send to monitoring system
if [ "$CLAUDE_TOOL_NAME" = "Stop" ]; then
# Session ended, send metrics
curl -X POST https://metrics.example.com/claude-usage \
-H "Content-Type: application/json" \
-d @~/.claude/usage.jsonl
# Clear log
> ~/.claude/usage.jsonl
fi

Automation Guidelines

DO:

  • Start simple and gradually add complexity
  • Test hooks thoroughly before deploying
  • Use timeouts to prevent hanging processes
  • Log automation results for debugging
  • Version control your automation scripts
  • Share successful patterns with your team

DON’T:

  • Over-automate to the point of losing control
  • Skip validation in automated workflows
  • Ignore error handling in scripts
  • Use overly permissive tool allowlists
  • Forget to document your automation

When building automation workflows, consider:

  1. Minimize context loading - Use focused prompts in headless mode
  2. Batch similar operations - Process multiple files in one session
  3. Cache common operations - Store results of expensive computations
  4. Use appropriate models - Sonnet 4 for simple tasks, Opus 4 for complex reasoning
  5. Monitor token usage - Track costs in automated workflows

Script automation in Claude Code transforms repetitive tasks into background magic. By mastering hooks, custom commands, headless mode, and automation patterns, you create workflows that handle the mundane while you focus on the creative. Start with simple formatting hooks, gradually build your command library, and soon you’ll have an automation suite that makes your entire team more productive. The key is finding the right balance – automate the repetitive, but maintain human oversight for the critical.