Skip to main content
What I Found Inside Claude Code's 513K Lines of Source Code
blog claude-code ai-agents deep-dive source-code

What I Found Inside Claude Code's 513K Lines of Source Code

MG
Manav Gupta
7 min read
Table of Contents

I spent the last week reading the source code of Claude Code — Anthropic’s AI coding agent. All 1,902 files. All 513,000 lines of TypeScript. What I found was a masterclass in building reliable, safe, and extensible AI tooling. Here’s the breakdown.

Why Read the Source?

Every AI company ships demos. Few ship source code you can actually read. Claude Code is different — it’s distributed as a CLI tool, and its TypeScript source is accessible. I wanted to understand not just what it does, but how it’s built. The architecture decisions reveal more about the state of AI engineering than any product announcement.

This article is a companion to the 20-page interactive deep dive — click through for code excerpts, detailed tables, and page-by-page analysis.

The Stack: Bun, Ink, Zustand

The first surprise: Claude Code doesn’t run on Node.js. It uses Bun, the newer JavaScript runtime built on the JavaScriptCore engine. The terminal UI is built with Ink — a heavily customized fork with a custom React reconciler, Yoga WASM flexbox layout, double-buffered ANSI rendering, and mouse tracking. 389 component files, 96 files in the Ink fork alone. State management uses Zustand with Immer for React-integrated UI state.

Metric Value
Source files 1,902
Lines of code ~513,000
Built-in tools 43
Slash commands 84
Environment variables 170+
React hooks 85
UI components 144 (in 389 files)

For the full technical breakdown, see the Overview & Stack companion page.

Architecture & Directory Structure

Claude Code — High-Level Architecture

The src/ directory is organized by function, not by feature. The biggest directories: utils/ (564 files — permissions, bash AST parser, sandbox, model routing, telemetry), components/ (389 files — Ink terminal UI), commands/ (207 files — 84 slash commands, 24+ internal-only), tools/ (184 files — 43 tool implementations), and services/ (130 files — API client, MCP protocol, streaming executor, analytics).

See the Architecture & Boot page for the full directory map.

The Query Loop: Where the Magic Happens

The Query Loop

At the heart of Claude Code is an async generator in query.ts — 1,729 lines. The REPL consumes streaming events via for await.

  1. User sends messagecreateUserMessage() wraps text in Anthropic format
  2. Compaction phase — four strategies checked: snip, microcompact, autocompact (at ~167K tokens), context collapse
  3. System prompt assembled from 10+ sources with cache_control markers
  4. Stream to Claude API via SSE — tokens parsed incrementally, rendered in real-time
  5. Tool execution starts BEFORE stream endsStreamingToolExecutor queues tool_use blocks as they arrive. Concurrent-safe tools run in parallel (max 10)
  6. Continue, retry, or return — tool_use loops back, prompt too long triggers compact, max tokens increases budget, 529 falls back to another model, end_turn returns

After each turn: auto-compact check, memory extraction via forked subagent, speculation (pre-computes next response), and autoDream (background memory consolidation after 24h + 5 sessions).

The Query Loop deep dive walks through each stage with code excerpts.

43 Tools — More Than You Think

StreamingToolExecutor Pipeline

Every tool implements a 30+ method interface: isConcurrencySafe(), isReadOnly(), isDestructive(), checkPermissions(). Fail-closed defaults.

File Operations: Read, Edit, Write, Glob, Grep, NotebookEdit. Execution: Bash, PowerShell. Search: WebFetch, WebSearch, ToolSearch. Agents: Agent, SendMessage, TaskCreate/Get/List/Update/Stop/Output, Plan modes, Worktree. MCP: MCPTool, ListMcpResources, ReadMcpResource, McpAuth. System: AskUser, TodoWrite, Skill, RemoteTrigger, Cron, Config, LSP, Brief.

Sibling Abort: When Bash errors, siblingAbortController.abort() cancels all parallel siblings instantly. Parent query continues.

Fork Cache: Fork subagents inherit byte-identical message history — only the directive differs. Shared prefix = prompt cache hit across all forks.

The Tool Catalog page has the full list with categories and descriptions.

The Permission Model Is Deeply Engineered

3-Layer Permission Model

The permission system has three layers:

  • Layer 1 — Tool Registry Filter: filterToolsByDenyRules() removes denied tools before Claude sees them. Claude cannot call what it cannot see.
  • Layer 2 — Per-Call Check: canUseTool() validates tool name, arguments, and working directory against allow/deny/ask rules.
  • Layer 3 — Interactive Prompt: If no rule matches: “allow once”, “allow always”, or “deny.” Response becomes a session-level rule.

7 operating modes range from default (prompt for risky tools only) through acceptEdits (auto-allow file edits), plan (read-only), auto (ML classifier decides), to bypassPermissions.

8-source rule priority: Policy → User → Project → Local → CLI flag → cliArg → command → session.

Bash AST Analysis: 24+ validators via tree-sitter parsing detect rm -rf, fork bombs, curl|bash, sudo, TTY injection, Unicode bypass, IFS injection, and more.

See the full Permissions and Security pages for details.

Context Management & Autocompact

Token Budget Distribution

Claude Code uses hybrid token counting — walks messages backwards to find last API usage data, then estimates new messages at character/4 with 4/3x padding. The autocompact threshold triggers at ~167K tokens (200K window minus 20K reserved minus 13K buffer).

4 compaction strategies:

  1. Snip — drop old messages entirely, no API call
  2. Microcompact — clear tool result content (time-based, cached, or compactable tools)
  3. Autocompact — Claude summarizes the conversation, frees ~40-60% of context
  4. Context Collapse — fold multiple messages into summaries

Circuit breaker: after 3 consecutive autocompact failures, stops attempting for the rest of the session.

See the Context & Autocompact page for the threshold math and strategy details.

The Subagent Swarm

3 Levels of Agent Parallelism

3 levels of parallelism: subagents (in-process, max 200 turns), fork subagents (byte-identical prefix for cache hits), and swarm teams (leader + teammates, file-based mailbox, 500ms permission poll).

The fork trick: buildForkedMessages() creates byte-identical prefixes with synthetic tool_result placeholders. Only the per-child directive differs. All forks share prompt cache — this is why Claude Code can cheaply spin up multiple parallel workers.

Swarm backends: In-Process (AsyncLocalStorage), Tmux (30/70 pane split), iTerm2 (vertical split tabs).

The Subagents & Swarm page has the full topology.

Memory: More Than Chat History

Memory System — 3-Layer Architecture

MEMORY.md is NOT a store — it’s a pointer index. Max 200 lines / 25KB. Each line: - [Title](file.md) — one-line hook.

  • Layer 1: MEMORY.md — always in system prompt
  • Layer 2: Topic files (*.md) — up to 5 auto-surfaced by Sonnet per turn as attachments
  • Layer 3: Transcripts (.jsonl) — grep-only, never fully read

4 types: user (role/preferences), feedback (corrections + confirmations), project (work/deadlines), reference (external system pointers).

autoDream: Fires after ≥24h + ≥5 sessions. 4 phases: Orient → Gather Signal → Consolidate → Prune & Index. PID-based lock with 60min stale guard.

See the Memory System page for the full architecture.

Security: 6-Layer Defense Stack

6-Layer Defense-in-Depth

Each layer is independent — compromising one doesn’t defeat the others.

  • Layer 0: Authentication — OAuth 2.0 + PKCE, macOS Keychain (90-day), JWT refresh (5min)
  • Layer 1: Permission Modes — 7 modes from default to bypassPermissions
  • Layer 2: Permission Rules — 8-source priority chain with pattern matching
  • Layer 3: Tool-Level Checks — 24+ bash validators, tree-sitter AST + regex
  • Layer 4: Pre/Post Tool Hooks — PreToolUse CAN block, 15s timeout
  • Layer 5: Sandboxing — macOS native, network allowlist, filesystem restrictions

Never-bypassable protections: .git/ directory protection (handles path escapes, NTFS 8.3, case-insensitive), symlink attack prevention, dangerous file protection (.gitconfig, .bashrc, .zshrc, .mcp.json), and policy sandbox restrictions that cannot be overridden.

Server-side killswitches can remotely disable bypassPermissions and the ML classifier.

See the Security page for the complete defense stack.

The Speculation System

Speculation System

While you’re reading Claude’s response, a background system pre-computes the next turn. Uses an overlay filesystem for safety.

A suggestion appears → overlay filesystem created → forked agent runs with REAL API calls → tool calls intercepted (read-only allowed, writes redirected to overlay, bash checked, others denied). Accept: copy overlay files to real filesystem, inject messages, appears instant. Abort: delete overlay, zero impact.

Pipelined: When Spec 1 completes, Spec 2 starts immediately for the NEXT turn — two steps ahead. Real API calls = real token cost.

See the Speculation page for the state machine details.

Architecture Critique

main.tsx is 4,684 lines with 187 imports in the first 210 lines. It serves as entry point AND orchestration — CLI parsing, init, feature flags, MCP config, session management, tool orchestration.

Principle Status Evidence
Single Responsibility Fail main.tsx has 6+ responsibilities
Open/Closed Fail God object knows everything
Dependency Inversion Fail 187 concrete imports
Testability Fail Side effects block unit tests
Modularity Partial Good tool system, poor boundaries

What’s good: Strong TypeScript types, modular tool system (30-method interface), memoization, separated query logic in QueryEngine.ts.

See the Architecture Critique page for the full SOLID scorecard.

The Easter Eggs

18 buddy species across 5 rarity tiers. Common (60%): duck, blob, cat, penguin, snail, rabbit. Epic (4%): capybara, robot. Legendary (1%): chonk. Deterministic from hash(userId). 1% shiny modifier.

Internal codenames: TENGU (project name), CHICAGO (computer use), KAIROS (assistant mode), AMBER QUARTZ (voice kill-switch), CHOMP (prompt suggestion system).

200+ spinner verbs: Clauding, Beboppin’, Boondoggling, Combobulating, Flibbertigibbeting, Hyperspacing, Lollygagging, Moonwalking, Quantumizing, Razzle-dazzling, Spelunking, Tomfoolering… and 183 more.

The Easter Eggs & Evolution page has the full collection.

What This Tells Us About AI Engineering

Claude Code is a genuinely sophisticated piece of software. The streaming tool executor that starts work before the API response completes, the copy-on-write speculation system, the 3-layer memory architecture with Sonnet-powered relevance ranking, the 6-layer defense stack with tree-sitter AST analysis — these are not trivial engineering achievements.

But the codebase also reveals the tension inherent in building at startup speed. A 4,684-line god object with 187 imports. Feature flag sprawl. Global mutable state. The architecture critique writes itself.

What’s most fascinating is what the source reveals about where the product is going: coordinator mode for multi-agent orchestration, pipelined speculation that thinks two steps ahead, team memory sync with conflict resolution, computer use with native macOS screen control, voice mode, and a buddy system with loot-box-style rarity tiers.

This is the first episode of a new Deep Dives series on Ship AI. If you prefer the video walkthrough, watch the episode. The full 20-page companion deck is at /deep-dives/claude-code/.

Share this article

Related Episodes

Dive deeper into these topics in the podcast.

Claude Code — Under the Covers
Deep Dive EP 1

Claude Code — Under the Covers

Apr 1, 2026 30 min

A source-code-level review of Anthropic's Claude Code — 1,902 files, 513K lines of TypeScript. We trace the query loop, catalog all 43 tools, dissect the 3-layer permission model, map the subagent ...

Enjoying this article?

Ship AI is a video podcast covering the trends, tools, and strategies driving enterprise AI. New episodes every two weeks.