CC
Claude Code
v2.1.88
Claude CodeArchitecture

Architecture

~1800 files

High-level system design of Claude Code — how the TypeScript monolith is organized, key abstractions, and the data flow between components.

TL;DR — Key Takeaways
  • Claude Code is a TypeScript monolith of ~512K lines across ~1,800 files — 3× larger than the Linux 1.0 kernel.
  • The entry point (cli.tsx) starts fast-path detection immediately, then spawns parallel init tasks: MDM, keychain, GrowthBook — all before the first user prompt.
  • QueryEngine.ts owns the conversation lifecycle: it assembles the system prompt, loads skills/plugins, and yields the first message to the loop.
  • query.ts is the heart — a 7-phase loop that handles context projection, streaming, tool execution, and token budget management. A single turn can call this loop many times.
512K
Lines of Code
TypeScript
1,884
Source Files
.ts / .tsx
43
Built-in Tools
Bash → MCP
101
Slash Commands
/compact → /stickers
System Architecture — at a glanceouter → inner = higher abstraction
Entry — cli.tsx / SDKfast-path + parallel init
QueryEngine.tsconversation lifecycle · system prompt · skills
query() loop — ~1700 lines
1
2
3
4
5
6
7
loop
Tools Layer
43 tools · Bash, Edit, Agent…
Services
MCP 470KB · Compact · LSP · Analytics
Bridge / Remote
Remote sessions via CCR
Utils— 220 files · zero inbound dependencies · everything imports from utils, nothing imports into it

Directory Structure

Use this map first if you need to orient yourself before diving into specific source files.

Codebase Scale
512Klines
~1,800files
3 Key Entry Points
entrypoints/cli.tsxBootstrap, fast-path & full init
QueryEngine.tsConversation lifecycle owner
query.ts7-phase agentic loop ~1700 lines
typescript
src/
├── entrypoints/       # CLI & SDK entry points
│   ├── cli.tsx        # Bootstrap, fast-path (--version, daemon)
│   └── sdk/           # Programmatic API for headless use
├── QueryEngine.ts     # Query lifecycle, message buffering
├── query.ts           # Main agentic loop state machine (~1700 lines)
├── Tool.ts            # Tool interface, ToolUseContext, buildTool()
├── Task.ts            # Task abstraction
│
├── tools/             # 50+ tool implementations
│   ├── BashTool/      # Command execution + security (300KB!)
│   ├── FileEditTool/  # String find/replace with diff
│   ├── FileReadTool/  # Read with PDF/notebook/image support
│   ├── AgentTool/     # Subagent spawning + isolation
│   ├── SkillTool/     # User-defined prompt templates
│   ├── MCPTool/       # External tool proxy (MCP protocol)
│   ├── GrepTool/      # Ripgrep-based search
│   ├── GlobTool/      # File pattern matching
│   └── shared/        # Git tracking, multi-agent spawn
│
├── services/          # Core backend services
│   ├── api/           # Claude API client + streaming
│   ├── compact/       # Context window management (13 files)
│   ├── mcp/           # MCP integration (25 files, 470KB!)
│   ├── lsp/           # Language Server Protocol
│   ├── extractMemories/  # Auto-memory background agent
│   ├── SessionMemory/ # Periodic conversation notes
│   ├── analytics/     # Event pipeline (Datadog + 1P)
│   ├── tools/         # Tool orchestration & streaming executor
│   └── plugins/       # Plugin management
│
├── context/           # Context management (CLAUDE.md, git, env)
├── state/             # Zustand-like AppState store
├── coordinator/       # Multi-worker orchestration
├── memdir/            # Memory directory system (~/.claude/projects/)
├── skills/            # Skill loading & bundled skills
├── commands/          # 90+ slash commands (/compact, /model, etc.)
├── bridge/            # Remote session bridge / control plane
├── remote/            # Remote session manager + websocket adapters
├── components/        # Ink UI components (React for terminal)
├── ink/               # Terminal rendering engine (custom fork)
├── hooks/             # React hooks + permission hooks
├── utils/             # Utilities (bash, git, permissions, etc.)
└── types/             # TypeScript type definitions

Claude Code is no longer just a REPL + tools. It now has bridge/remote subsystems, speculation services, and rich session infrastructure around the core query loop.

🏛️

Key Insight

The /utils directory has 220 files but zero inbound package dependencies — it's the foundation everything builds on. Nothing in the codebase imports into utils; everything imports from it.

Core Abstractions

These abstractions are the vocabulary of the rest of the system.

QueryEngine

Owns the complete conversation lifecycle. Async generator that yields SDKMessage objects. Handles system prompt assembly, user input processing, and delegates to query() loop.

query()

The main agentic loop — a state machine that streams API responses, executes tools, handles recovery, and decides whether to continue or exit.

Tool<Input, Output, Progress>

Unified interface for all tools. Built via buildTool() factory. Declares permissions, concurrency safety, and rendering.

ToolUseContext

Central communication channel between tools and the query loop. Contains options, state accessors, abort controller, analytics.

Async Generator Architecture

Both QueryEngine and query() are async generators that yield intermediate results for real-time streaming.

Streaming Concurrency

Tools start executing while the model is still generating. StreamingToolExecutor queues tool_use blocks as they arrive.

Cache Sharing (CacheSafeParams)

Frozen system prompt bytes enable zero-cost forked queries for subagents. Identical bytes = automatic prompt cache hit.

DeepImmutable State

Zustand-like AppState with type-safe mutations. setAppState(prev => {...prev, field: newValue}).

High-Level Data Flow

Visual walkthrough of a request from entry to terminal state.

Entry Pointcli.tsx / SDK

Fast-path: --version, daemon workers | Full init: MDM, keychain, GrowthBook (~135ms parallel)

delegates to
QueryEngineQueryEngine.ts

System prompt assembly · User input processing · Skill & plugin loading · Yield init message

delegates to
query() Loopquery.ts ~1700 linesloops while tools called

Context projection · Auto-compaction · API streaming · Tool execution · Attachments · Continuation

delegates to
Terminal StateSession ends

completed · prompt_too_long · aborted · token_budget_completed

A second top-level flow now exists beside the local REPL path: bridge/remote execution. In that mode, a bridge loop polls for work, spawns or reconnects sessions, and lets the same QueryEngine/query() core run inside managed remote capacity. Architecturally, that means the agent loop is the center, but not the whole product anymore.

AppState Families

Runtime

remoteConnectionStatus · replBridgeConnected · remoteBackgroundTaskCount

Agent Orchestration

tasks · agentNameRegistry · coordinatorTaskIndex · viewingAgentTaskId

Background Intelligence

promptSuggestionEnabled · speculationState · notifications · elicitation

UX Subsystems

companionReaction · bagelActive · tungstenActiveSession · footerSelection

Codebase Size Comparison

Lines of code compared to well-known projects (approximate):

Linux 1.0 (1994)
176K
jQuery 3.x
10K
Express.js
14K
React (core)
200K
Claude Code v2.1.88
513K

Top 10 Largest Files

Use this table when you want to know where the codebase is densest and worth deeper reading.

1cli/print.ts
5,594
2utils/messages.ts
5,512
3utils/sessionStorage.ts
5,105
4utils/hooks.ts
5,022
5screens/REPL.tsx
5,005
6main.tsx
4,683
7utils/bash/bashParser.ts
4,436
8utils/attachments.ts
3,997
9services/api/claude.ts
3,419
10services/mcp/client.ts
3,348
📏

Key Insight

print.ts is 5,594 lines and does ONE thing: format terminal output. That's more lines than the entire React core scheduler. When output formatting gets complex enough, it becomes its own subsystem.

Technology Stack

TechnologyUsageNotes
TypeScriptPrimary languageStrict mode, Zod for runtime validation
Ink (React)Terminal UICustom fork with layout engine, focus, selection
ZodSchema validationTool input/output schemas, config validation
Yoga LayoutTerminal layoutFlexbox for terminal via yoga-layout
RipgrepFile searchGrepTool wraps rg for fast content search
Tree-sitterBash parsingAST-based security analysis of shell commands
SharpImage processingResize/compress images for API token limits
MCP ProtocolExternal toolsstdio, SSE, HTTP, WebSocket transports
GrowthBookFeature flagsA/B testing with cached gate values

Key Insight

Claude Code uses a CUSTOM FORK of Ink — they've modified the terminal rendering engine itself. The ink/ directory isn't just configuration; it's a patched version of React-for-terminals with layout engine changes, focus management, and selection behavior Anthropic needed but upstream doesn't have.