Chapter 3
15 min read
Section 16 of 175

Claude Code Architecture Overview

How Claude Code Works

Introduction

Claude Code is Anthropic's terminal-native agentic coding assistant. It represents one of the most sophisticated production agent systems available today, combining deep codebase understanding with powerful tool use. This chapter dissects how Claude Code works, extracting patterns you can apply to your own agents.

Learning from the Best: Claude Code isn't just a product - it's a reference implementation of agentic best practices. Understanding its architecture will make you a better agent developer.

What is Claude Code

Claude Code is an agentic coding assistant that runs in your terminal. Unlike IDE-integrated tools, it:

  • Runs locally: Executes on your machine with full filesystem access
  • Terminal-native: Lives in your terminal, not an IDE
  • Agentic: Takes autonomous actions to accomplish goals
  • Context-aware: Understands your entire codebase
  • Tool-rich: Can read, write, search, execute, and more
⚑claude_code_usage.sh
1# Basic usage
2$ claude "Add input validation to the signup form"
3
4# Claude Code will:
5# 1. Search for the signup form in your codebase
6# 2. Analyze the current implementation
7# 3. Identify what validation is needed
8# 4. Implement the validation
9# 5. Test the changes
10# 6. Report what was done
11
12# Continue a conversation
13$ claude --continue "Now add error messages for each field"
14
15# Run with specific context
16$ claude --context src/components "Refactor the Button component"

High-Level Architecture

πŸ“claude_code_architecture.txt
1β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
2β”‚                      CLAUDE CODE                            β”‚
3β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
4β”‚                                                             β”‚
5β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
6β”‚  β”‚   CLI/Terminal  │───▢│      Conversation Manager       β”‚ β”‚
7β”‚  β”‚    Interface    β”‚    β”‚   (History, Context, State)     β”‚ β”‚
8β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
9β”‚                                        β”‚                    β”‚
10β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
11β”‚  β”‚                   AGENT LOOP                           β”‚ β”‚
12β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚ β”‚
13β”‚  β”‚  β”‚ Perceive │─▢│  Reason  │─▢│   Act    │─▢│Observe β”‚  β”‚ β”‚
14β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚ β”‚
15β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
16β”‚                           β”‚                                 β”‚
17β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
18β”‚  β”‚                    TOOL SYSTEM                         β”‚ β”‚
19β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”  β”‚ β”‚
20β”‚  β”‚  β”‚  Read  β”‚ β”‚ Write  β”‚ β”‚ Search β”‚ β”‚ Executeβ”‚ β”‚ Bash β”‚  β”‚ β”‚
21β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”˜  β”‚ β”‚
22β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
23β”‚                                                             β”‚
24β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
25β”‚  β”‚                  CONTEXT SYSTEM                        β”‚ β”‚
26β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚ β”‚
27β”‚  β”‚  β”‚ CLAUDE.md β”‚ β”‚ Agentic      β”‚ β”‚ Codebase Index   β”‚   β”‚ β”‚
28β”‚  β”‚  β”‚ Context   β”‚ β”‚ Search       β”‚ β”‚ (On-demand)      β”‚   β”‚ β”‚
29β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
30β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
31β”‚                                                             β”‚
32β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Three-Layer Architecture

LayerResponsibilityComponents
InterfaceUser interactionCLI, Terminal UI, History
Agent CoreDecision and executionAgent loop, LLM reasoning
Tool SystemWorld interactionFile ops, search, execution
Context SystemKnowledge managementCLAUDE.md, agentic search, indexing

Key Components

1. The CLI Interface

The command-line interface handles user input and displays agent output:

🐍cli_interface.py
1# Conceptual CLI structure (not actual Claude Code source)
2class ClaudeCodeCLI:
3    def __init__(self):
4        self.conversation = ConversationManager()
5        self.agent = Agent()
6
7    def run(self, command: str, options: dict):
8        # Load context
9        context = self.load_context(options)
10
11        # Run agent
12        result = self.agent.run(
13            goal=command,
14            context=context,
15            conversation=self.conversation,
16        )
17
18        # Display result
19        self.display(result)
20
21    def load_context(self, options: dict) -> Context:
22        context = Context()
23
24        # Load CLAUDE.md files
25        context.add(self.load_claude_md())
26
27        # Load conversation history if continuing
28        if options.get("continue"):
29            context.add(self.conversation.recent_history())
30
31        # Add specified context paths
32        if options.get("context"):
33            context.add(self.scan_paths(options["context"]))
34
35        return context

2. The Agent Core

The central loop that orchestrates reasoning and action:

🐍agent_core.py
1class Agent:
2    def run(self, goal: str, context: Context) -> AgentResult:
3        state = AgentState(goal=goal)
4
5        while not state.should_stop():
6            # Perceive: Gather relevant context
7            current_context = self.gather_context(state, context)
8
9            # Reason: Call Claude with tools
10            response = self.claude.generate(
11                messages=current_context.messages,
12                tools=self.tools.schemas,
13                system=current_context.system_prompt,
14            )
15
16            # Act: Execute any tool calls
17            if response.has_tool_calls():
18                for tool_call in response.tool_calls:
19                    result = self.tools.execute(tool_call)
20                    state.add_observation(tool_call, result)
21            else:
22                # No tools called - text response
23                state.add_response(response.text)
24
25            # Check for completion
26            if self.is_complete(state, response):
27                state.complete()
28
29        return state.result()

3. The Tool System

A comprehensive set of tools for interacting with the filesystem and environment:

ToolPurposeKey Capability
ReadRead file contentsAny text file, binary detection
WriteCreate/modify filesAtomic writes, backup support
EditPrecise editsLine-based replacement
GlobFind files by patternFast pattern matching
GrepSearch file contentsRegex support, context lines
BashRun commandsSandboxed execution
WebFetchFetch web contentDocumentation, research
TaskSpawn subagentsParallel exploration

4. The Context System

Intelligent context gathering that ensures Claude has the information it needs:

🐍context_system.py
1class ContextSystem:
2    """Manages context for the agent."""
3
4    def gather(self, state: AgentState) -> Context:
5        context = Context()
6
7        # 1. Load CLAUDE.md hierarchy
8        context.add(self.load_claude_md_files())
9
10        # 2. Add conversation history (summarized if long)
11        context.add(self.summarize_history(state.history))
12
13        # 3. Agentic search for relevant files
14        if state.needs_context:
15            relevant = self.agentic_search(state.current_focus)
16            context.add(relevant)
17
18        # 4. Add recent observations
19        context.add(state.recent_observations)
20
21        return context
22
23    def load_claude_md_files(self) -> list[str]:
24        """Load CLAUDE.md from home and project directories."""
25        files = []
26
27        # Home directory (global defaults)
28        home_claude_md = Path.home() / "CLAUDE.md"
29        if home_claude_md.exists():
30            files.append(home_claude_md.read_text())
31
32        # Project root and subdirectories
33        for claude_md in Path.cwd().rglob("CLAUDE.md"):
34            files.append(claude_md.read_text())
35
36        return files

Execution Flow

Here's what happens when you run a Claude Code command:

  1. Parse command: CLI parses your input and options
  2. Load context: CLAUDE.md files, history, specified paths
  3. Initialize agent: Create state, prepare tool registry
  4. Agent loop: Perceive β†’ Reason β†’ Act β†’ Observe (repeat)
  5. Tool execution: Run tools as Claude requests them
  6. Stream output: Display Claude's reasoning and actions
  7. Save state: Update conversation history
πŸ“execution_example.txt
1$ claude "Add a loading spinner to the submit button"
2
31. [Context] Loading CLAUDE.md, scanning project structure...
42. [Search] Looking for submit button implementation...
5   Found: src/components/Button.tsx, src/pages/Form.tsx
63. [Read] Reading src/components/Button.tsx...
74. [Reason] Planning how to add loading state...
85. [Edit] Modifying Button.tsx to accept 'loading' prop...
96. [Edit] Updating Form.tsx to pass loading state...
107. [Verify] Checking for TypeScript errors...
118. [Complete] Added loading spinner with 3 file changes.

Design Principles

1. Terminal-Native

Claude Code runs in the terminal, not an IDE. This means:

  • Works with any editor or workflow
  • Accessible via SSH on remote machines
  • Scriptable and automatable
  • Lightweight compared to IDE plugins

2. Context Engineering

The CLAUDE.md system lets developers customize agent behavior:

πŸ“CLAUDE.md
1# Project Guidelines for Claude
2
3## Architecture
4This is a Next.js 14 app with TypeScript and Tailwind.
5Use the App Router pattern for all new pages.
6
7## Code Style
8- Use functional components with hooks
9- Prefer named exports
10- Keep components under 200 lines
11
12## Testing
13- Write tests for all new features
14- Use React Testing Library, not Enzyme
15
16## Don't
17- Never modify files in /generated
18- Don't use any CSS-in-JS libraries

Rather than loading the entire codebase, Claude Code intelligently searches for relevant context as needed.

4. Safety First

  • Permission prompts for destructive actions
  • Sandboxed command execution
  • Clear display of all file changes
  • Easy undo through git integration

Learn from Production

Claude Code represents years of iteration on agentic systems. The patterns here - context engineering, agentic search, safety prompts - are battle-tested in production.

Summary

Claude Code's architecture teaches us:

  1. Terminal-native: Agents don't need heavy IDEs
  2. Three layers: Interface, agent core, tool system
  3. Rich tools: Read, write, search, execute capabilities
  4. Context system: CLAUDE.md + agentic search
  5. Safety: Permissions, sandboxing, transparency
Next: Let's explore the terminal-first philosophy and why it matters for agent design.