Skip to content

How Claude Code Works β€” Deep Dive

Claude Code is not a chatbot. It is an agent β€” a system that takes actions, observes results, and loops until the task is done.

User prompt
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Plan: what steps are needed? β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Choose a tool call β”‚ ◄─────────┐
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ Execute the tool β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ Observe the result β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ Task complete? │── No β”€β”€β”€β”€β”€β”€β”€β”˜
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ Yes
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Reply to user β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

This loop runs entirely on Claude’s side. You see the final answer, but many tool calls may happen silently in between.

Everything Claude does is through tools. Claude cannot do anything that isn’t backed by a tool.

ToolWhat it does
ReadRead a file from disk
WriteCreate a new file
EditModify part of an existing file
GlobFind files by pattern
GrepSearch file contents with regex
BashExecute a shell command
WebFetchFetch a URL
WebSearchSearch the web
AgentSpawn a subagent
TodoWrite / TodoReadManage task lists
  1. Claude decides it needs to read a file
  2. Claude generates a tool call: Read("src/index.ts")
  3. The harness intercepts β€” checks permissions
  4. If allowed: executes the read, returns content
  5. If denied (or user says no): Claude sees an error and adjusts
  6. Claude incorporates the file content and continues planning

Claude can issue multiple tool calls in a single step when they are independent:

Step 1: Read("src/auth.ts"), Read("src/routes.ts"), Read("tests/auth.test.ts")
↓ all three run in parallel ↓
Step 2: Edit("src/auth.ts") based on findings

This is why Claude Code is fast β€” it doesn’t wait for each read one by one.

Claude’s context window at any point contains:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ System prompt (built-in + CLAUDE.md) β”‚
β”‚ Auto memory index (MEMORY.md) β”‚
β”‚ Project files (if loaded) β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Conversation history β”‚
β”‚ β”œβ”€β”€ User messages β”‚
β”‚ β”œβ”€β”€ Claude's text responses β”‚
β”‚ └── Tool call results (file contents, β”‚
β”‚ command output, search results) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Context window size is finite. As the conversation grows, older content is compressed or dropped. The /compact command or auto-compact (when enabled) summarizes the conversation to free space.

Claude does NOT load your entire codebase upfront. It reads files on demand as it needs them.

The typical flow for β€œfix this bug”:

  1. Claude reads the file mentioned in your prompt
  2. Discovers imports β†’ reads those files
  3. Discovers the test file β†’ reads it
  4. Reads related config if needed
  5. Makes targeted edits

This is why naming the file in your prompt helps: it tells Claude where to start.

Session start
β”‚
β–Ό
Load managed CLAUDE.md (org-wide)
β”‚
β–Ό
Load ~/.claude/CLAUDE.md (user)
β”‚
β–Ό
Load ./CLAUDE.md or ./.claude/CLAUDE.md (project)
β”‚
β–Ό
Load ./CLAUDE.local.md (personal, gitignored)
β”‚
β–Ό
Load .claude/rules/*.md for any files already in context
β”‚
β–Ό
All loaded content goes into the system prompt

Import resolution: @./path/to/file.md is resolved once at load time and the file content is inlined. It is not re-read on every turn.

Path-scoped rules are loaded dynamically: when Claude opens a file that matches a rule’s paths: pattern, that rule file is added to the context for that turn.

A session = one conversation thread with a unique ID.

~/.claude/projects/<project-hash>/sessions.jsonl

Each session stores:

  • All messages and tool calls
  • Which files were read/edited
  • Timestamps and cost

Session lifecycle:

  • claude β†’ new session
  • claude --continue β†’ resumes most recent session
  • claude --resume β†’ pick any past session
  • Ctrl+D or /exit β†’ ends session cleanly

Sessions are kept for cleanupPeriodDays (default 30 days), then purged.

User types a prompt
β”‚
β–Ό
Claude plans a tool call
β”‚
β–Ό
Harness checks: is this tool in the allow list?
β”‚
β”œβ”€β”€ Yes, pre-approved β†’ execute immediately
β”‚
β”œβ”€β”€ No, in deny list β†’ return error to Claude
β”‚
└── Unknown β†’ check defaultMode
β”‚
β”œβ”€β”€ default / acceptEdits β†’ prompt user
β”‚ User approves β†’ execute
β”‚ User denies β†’ return error
β”‚
β”œβ”€β”€ auto β†’ analyze safety β†’ execute or prompt
β”‚
β”œβ”€β”€ plan β†’ block all writes/shell
β”‚
└── bypassPermissions β†’ execute always

Pre-approved tools (in allow list) never prompt. This is why configuring your allow list in .claude/settings.json makes your workflow much smoother.

During a session:
Claude notices something worth remembering
(e.g. "tests require npm install first")
β”‚
β–Ό
Claude calls Write / Edit on a file in
~/.claude/projects/<hash>/memory/
β”‚
β–Ό
Updates MEMORY.md index
Next session:
MEMORY.md is loaded into system prompt
Claude reads referenced memory files on demand

The memory system is just files β€” you can read, edit, or delete them at any time.

When Claude spawns a subagent:

Main Claude session
β”‚
β”‚ Agent("Explore", "find all auth middleware")
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ New Claude instance β”‚
β”‚ - Fresh context window β”‚
β”‚ - Inherits tool permissions β”‚
β”‚ - Isolated from main sessionβ”‚
β”‚ - Runs in parallel (opt) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”‚ Returns: result text
β–Ό
Main Claude continues with result

Subagents:

  • Have their own isolated context (they don’t see your full conversation)
  • Can be given restricted tool lists
  • Can run in separate git worktrees (so their file edits don’t conflict)
  • Are billed separately (their tokens count toward your usage)
  1. Your message is appended to the conversation
  2. All registered hooks for PreMessage fire (if any)
  3. Claude processes the full context and generates a response
  4. If the response contains tool calls, the harness executes them
  5. Tool results are added to context
  6. Claude generates the next response
  7. This repeats until Claude produces a final text-only response
  8. PostMessage hooks fire
  9. The response is displayed to you

When the context grows large:

  1. /compact or auto-compact triggers
  2. Claude is asked to summarize the conversation so far
  3. The summary replaces the conversation history
  4. Full context of recently-read files is retained
  5. The summary is much smaller β†’ Claude can continue

This is lossy β€” detail from early in the conversation may be lost. Use /recap before /compact to preserve a human-readable summary.

  • Trick: β€œOne model + tools in a loop β€” no magic.”
  • Everything is visible: Ctrl+O shows the full transcript.
  • Say: understanding the loop is what demystifies every failure later.
  • Show: one turn in verbose transcript β€” name each tool call as it streams.
  • They’ll trip on: thinking Claude β€œremembers” β€” every turn re-sends everything (caching makes it cheap).

Learning path: β¬… 05-interactive-mode-shortcuts.md Β· Index Β· ➑ 07-tools-deep-dive.md

Written by Fenil Patel