What I Found Inside Claude Code's 513K Lines of Source Code
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

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

At the heart of Claude Code is an async generator in query.ts — 1,729 lines. The REPL consumes streaming events via for await.
- User sends message —
createUserMessage()wraps text in Anthropic format - Compaction phase — four strategies checked: snip, microcompact, autocompact (at ~167K tokens), context collapse
- System prompt assembled from 10+ sources with
cache_controlmarkers - Stream to Claude API via SSE — tokens parsed incrementally, rendered in real-time
- Tool execution starts BEFORE stream ends —
StreamingToolExecutorqueues tool_use blocks as they arrive. Concurrent-safe tools run in parallel (max 10) - 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

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

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

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:
- Snip — drop old messages entirely, no API call
- Microcompact — clear tool result content (time-based, cached, or compactable tools)
- Autocompact — Claude summarizes the conversation, frees ~40-60% of context
- 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 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.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

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

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/.
Related Episodes
Dive deeper into these topics in the podcast.
Claude Code — Under the Covers
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.