Master Claude Code
from Scratch
Everything you need to know — from what a coding assistant is, to custom hooks and the SDK. Verified, organized, and built for focused learning.
- 01 What is a Coding Assistant?
- 02 What is Claude Code?
- 03 How Tool Use Works
- 04 Claude Code in Action
- 05 Adding Context
- 06 Making Changes & Power Modes
- 07 Controlling Context
- 08 Custom Commands
- 09 MCP Servers
- 10 GitHub Integration
- 11 Hooks — Automating Quality
- 12 Gotchas Around Hooks
- 13 Useful Hooks — Real Examples
- 14 The Claude Code SDK
What is a Coding Assistant?
A coding assistant is a tool that sits between you and a language model (like Claude), helping you write, fix, and manage code. It can read your files, run your tests, and make changes — all from a single conversation.
The Core Workflow
Imagine hiring a freelance developer. You email them: "our checkout page is broken." A good developer doesn't guess — they look at the code, reproduce the issue, trace the logic, then fix it. A coding assistant works the same way, but faster.
Language models can only process text input and produce text output. They cannot directly read files, run commands, or interact with external systems. This is why tool use is essential.
What is Claude Code?
Claude Code is Anthropic's official coding assistant built on the Claude language model. You interact with it through the terminal, and it can read files, write code, run commands, and connect to external services.
Why Claude Code?
| Feature | What It Means for You |
|---|---|
| Superior tool use | Exceptionally good at knowing which tool to use and when — better than competing models |
| Extensible by design | Plug in new tools (browsers, databases, APIs) as your needs grow via MCP servers |
| Better security | Searches your code directly — doesn't send your entire codebase to external indexing servers |
| Complex task handling | Chains multiple tools together to solve multi-step problems effectively |
How Tool Use Works
This is the most important concept to internalize. Language models can only process text. They cannot open a file, run a command, or check a website on their own. Tool use is the mechanism that bridges this gap.
Step-by-Step Breakdown
// 1. You ask:
"What's in my package.json?"
// 2. Claude Code adds instructions to the request:
"If you need to read a file, respond with: READ_FILE: <filename>"
// 3. The language model responds:
READ_FILE: package.json
// 4. Claude Code (assistant layer) actually reads the file
// 5. File contents are sent back to the language model
// 6. Claude reads the content and gives you a real answer
Think of a surgeon and a scrub nurse. The surgeon (language model) says "scalpel" and the nurse (Claude Code) physically hands it over. The surgeon has the knowledge; the nurse does the physical work. Together they complete the operation.
All language models require tool use for non-text tasks. The quality of tool use directly impacts how effective a coding assistant is. Claude's strength here is what makes Claude Code powerful.
Claude Code in Action
Example 1 — Performance Optimization
Claude analyzed the Chalk JavaScript library (~430M weekly downloads) and achieved a 3.9× throughput improvement:
Example 2 — PII Security Detection
A developer adds user email to a Lambda function output. Claude Code, running on GitHub Actions, reads the Terraform infrastructure, traces data flow, detects that emails now reach an external S3 bucket shared with a partner, and posts a warning before merge.
Example 3 — Data Analysis
Point Claude at a CSV of customer data. It opens a Jupyter notebook, writes and runs cells iteratively, identifies churn patterns, and produces charts — all in one conversation.
Adding Context
Claude works best when it understands your project. Too little context gives wrong answers. Too much irrelevant context makes it slower and less accurate. The goal is just enough.
The /init Command
/init
Scans your entire codebase, understands the architecture, and creates a Claude.md file. This file is automatically included in every future request.
Three Types of Claude.md
| Type | Committed? | Use Case |
|---|---|---|
| Project level | ✓ Yes | Architecture, coding standards, key files — shared with team |
| Local level | ✗ No | Personal preferences, notes just for you |
| Machine level | ✗ No | Global preferences across all your projects |
Example Claude.md
## Project: E-commerce Platform
- Database schema → /db/schema.sql (always reference for DB questions)
- We use PostgreSQL, not MySQL
- Auth handled by /src/auth/middleware.ts
- Never modify files in /vendor/
The @ Symbol — Pinpoint Context
@src/auth/middleware.ts — why is the login token expiring early?
Mention files directly instead of letting Claude search. It's like handing a new employee the exact page they need instead of saying "the answer is somewhere in the wiki."
The # Symbol — Memory Mode
# Always use async/await instead of .then() chains
Immediately updates your Claude.md so Claude remembers this in all future interactions.
Making Changes & Power Modes
Pasting Screenshots — Ctrl+V
Use Control+V, not Command+V. Command+V does not paste screenshots into Claude Code on macOS.
Screenshot a broken UI element, paste it, and say "fix the alignment here." No need to describe what you see in words.
Plan Mode — For Breadth
Activate with Shift + Tab (twice). Claude will research all relevant files, build a detailed plan, and only then start making changes. Ideal for multi-file features and refactoring.
Thinking Mode — For Depth
Include phrases like "Ultra think" in your message. Gives Claude an extended reasoning budget for complex logic and subtle bugs.
Ultra think — why does our payment processing occasionally fail
for orders placed exactly at midnight?
When to Use Each Mode
| Mode | Handles | Best For |
|---|---|---|
| Plan Mode | Breadth | Multi-step tasks, wide codebase understanding |
| Thinking Mode | Depth | Tricky logic, debugging specific issues |
| Both combined | Breadth + Depth | The most complex tasks you face |
Both modes consume additional tokens. Use them strategically rather than on every request.
Git Integration
Claude Code can stage files, create commits, and write descriptive commit messages automatically. Just say "commit the changes you just made."
Controlling Context
Long conversations accumulate noise that can confuse Claude. These tools keep you focused:
Use Double Escape when you've gone down a debugging rabbit hole for 10+ messages with no results. Jump back to before the rabbit hole and try a different approach — without losing relevant context.
Custom Commands
Custom commands let you create your own slash commands to automate repetitive tasks.
How to Create One
.claude/commands/ in your project rootaudit.md → /auditExample — /audit Command
Audit all npm dependencies in package.json for known vulnerabilities.
For each vulnerable package:
1. List the package name and current version
2. Describe the vulnerability
3. Suggest the safest upgrade path
Commands with Arguments
Generate comprehensive unit tests for the file at: $arguments
Include tests for:
- Happy path
- Edge cases
- Error handling
/test src/components/Button.tsx
MCP Servers — Extending Claude's Abilities
MCP (Model Context Protocol) servers are external tools you plug into Claude Code to give it new capabilities. Think of them as "apps" Claude can use — browsers, databases, design tools, and more.
Installing an MCP Server
# Install the Playwright browser automation server
claude mcp add playwright npx @playwright/mcp
Auto-Approving MCP Tools
{
"allow": ["MCP__playwright"]
}
Real World — Automated UI Refinement
localhost:3000 in a real browserGitHub Integration
Claude Code can run directly inside GitHub Actions, triggered by pull requests and issues.
Setup
/install-github-app
This auto-creates two GitHub Actions in your repo:
| Action | What It Does |
|---|---|
| Mention support | Tag @claude in any issue or PR comment to assign Claude a task |
| PR review | Claude automatically reviews every new pull request |
You must explicitly list all permissions for Claude Code in your Actions config. MCP server tools require individual permission listing — there are no shortcuts.
Hooks — Automating Quality Control
Hooks are custom scripts that run automatically before or after Claude uses a tool. They let you enforce rules, run checks, and provide automated feedback.
The Two Hook Types
| Type | When It Runs | Can Block? |
|---|---|---|
| Pre-tool use | Before Claude executes a tool | ✓ Yes (exit 2) |
| Post-tool use | After Claude executes a tool | ✗ No |
How a Hook Decision Works
.env?exit(2) — Claude is blocked + gets your error message via stderrexit(0) — Claude proceeds normallyConfiguration
{
"hooks": {
"preToolUse": [
{
"matcher": "read|grep",
"command": "node /absolute/path/to/hooks/read_hook.js"
}
]
}
}
Hook Script Example
const chunks = [];
process.stdin.on('data', chunk => chunks.push(chunk));
process.stdin.on('end', () => {
const data = JSON.parse(Buffer.concat(chunks).toString());
const filePath = data.tool_input?.path || '';
if (filePath.includes('.env')) {
console.error('Blocked: .env files are off-limits for security');
process.exit(2); // Block the tool call
}
process.exit(0); // Allow the tool call
});
The hook receives a JSON object via stdin containing: session_id, tool_name (e.g., "read" or "grep"), and tool_input (including the file path). Your script parses this and exits with the appropriate code.
Gotchas Around Hooks
The Absolute Path Problem
Claude Code recommends absolute paths in hook commands for security (prevents path interception attacks). But absolute paths are machine-specific, making it hard to share settings with your team.
Your machine: /Users/alice/myproject/hooks/read_hook.js
Colleague's machine: /Users/bob/work/myproject/hooks/read_hook.js
Committing your path breaks it for everyone else.
The Solution — Template + Setup Script
Create a settings.example.json template with a $PWD placeholder:
{
"hooks": {
"preToolUse": [{
"matcher": "read|grep",
"command": "node $PWD/hooks/read_hook.js"
}]
}
}
A scripts/init-claude.js setup script replaces $PWD with each developer's actual project path when they run:
npm run setup # installs deps + generates settings.local.json
Commit settings.example.json to git. Add settings.local.json to .gitignore. Every developer gets correct absolute paths automatically.
You must restart Claude Code after any hook configuration changes for them to take effect.
Useful Hooks — Real Examples
Hook 1 — TypeScript Type Checker
The problem: Claude edits a function's signature but forgets to update all call sites, leaving type errors scattered in the codebase.
The solution: A post-tool-use hook that runs tsc --no-emit after every file edit:
const { execSync } = require('child_process');
try {
execSync('tsc --no-emit', { stdio: 'pipe' });
process.exit(0);
} catch (error) {
// Feed type errors back to Claude as feedback
console.error('TypeScript errors:\n' + error.stdout.toString());
process.exit(0); // post-hook can't block, but Claude reads the feedback
}
Works for any typed language with a type checker. For untyped languages, run your test suite instead of tsc.
Hook 2 — Duplicate Code Prevention
The problem: In complex multi-step tasks, Claude creates new queries/functions instead of reusing existing ones.
The solution: A post-tool hook launches a second Claude instance via the SDK to check for duplicates when a watched directory is edited.
/queries/ is modifiedexit(2) + "Use existing query X instead"✅ Cleaner codebase | ✅ Fewer bugs from duplicate logic | ❌ Slower | ❌ Higher token cost. Apply only to critical directories — not globally.
The Claude Code SDK
The Claude Code SDK lets you use Claude Code programmatically — in your own scripts, CI pipelines, and hooks — rather than just through the terminal.
Available for CLI, TypeScript / JavaScript, and Python.
Default Permissions
By default, SDK instances only have read access (files, directories, grep). You must explicitly enable write operations via options.allowTools.
Basic Usage
import { query } from '@anthropic-ai/claude-code';
const result = await query({
prompt: 'Refactor getUserById to be async',
options: {
allowTools: ['read', 'edit', 'grep'] // explicitly enable write
}
});
// The final message is Claude's last response
const response = result.messages[result.messages.length - 1];
Best Suited For
| Use Case | Example |
|---|---|
| Hooks (like duplicate detection) | Second Claude instance reviewing changes |
| CI / CD pipelines | Automated code quality review on every push |
| Custom helper scripts | Pre-migration schema analysis |
Quick Reference Cheat Sheet
Ctrl+VPaste screenshot into promptShift+Tab ×2Enable Plan ModeEscape ×1Stop Claude mid-responseEscape ×2Rewind conversation history/initAnalyze codebase, create Claude.md/compactSummarize + clear clutter/clearFull reset — fresh start/hooksConfigure hooks interactively@fileInclude specific file in context# instructionAdd permanent memory to Claude.mdUltra thinkExtended reasoning modeexit(0)Allow the tool call to proceedexit(2)Block tool call (pre-hook only)stderrFeedback message sent to Claude1. Install Claude Code and run /init → 2. Try a simple bug fix task → 3. Add a Claude.md with your key files → 4. Create one custom command → 5. Explore MCP servers → 6. Add hooks for quality checks. The more context and structure you give Claude, the better it performs.