Deep-dive into how Claude Code is structured internally.
Claude Code is a terminal-native AI coding assistant built as a single-binary CLI. The architecture follows a pipeline model:
User Input → CLI Parser → Query Engine → LLM API → Tool Execution Loop → Terminal UI
The entire UI layer is built with React + Ink (React for the terminal), making it a fully reactive CLI application with components, hooks, state management, and all the patterns you’d expect in a React web app — just rendered to the terminal.
src/main.tsx)The CLI parser is built with Commander.js (@commander-js/extra-typings). On startup, it:
src/replLauncher.tsx)src/entrypoints/)| File | Role |
|---|---|
cli.tsx |
CLI session orchestration — the main path from launch to REPL |
init.ts |
Config, telemetry, OAuth, MDM policy initialization |
mcp.ts |
MCP server mode entrypoint (Claude Code as an MCP server) |
sdk/ |
Agent SDK — programmatic API for embedding Claude Code |
Startup performs parallel initialization: MDM policy reads, Keychain prefetch, feature flag checks, then core init.
src/QueryEngine.ts, ~46K lines)The heart of Claude Code. Handles:
src/Tool.ts + src/tools/)Every capability Claude can invoke is a tool. Each tool is self-contained with:
Tools are registered in src/tools.ts and discovered by the Query Engine during tool-call loops.
See Tools Reference for the complete catalog.
src/commands.ts + src/commands/)User-facing slash commands (/commit, /review, /mcp, etc.) that can be typed in the REPL. Three types:
| Type | Description | Example |
|---|---|---|
| PromptCommand | Sends a formatted prompt to the LLM with injected tools | /review, /commit |
| LocalCommand | Runs in-process, returns plain text | /cost, /version |
| LocalJSXCommand | Runs in-process, returns React JSX | /doctor, /install |
Commands are registered in src/commands.ts and invoked via /command-name in the REPL.
See Commands Reference for the complete catalog.
Claude Code uses a React context + custom store pattern:
| Component | Location | Purpose |
|---|---|---|
AppState |
src/state/AppStateStore.ts |
Global mutable state object |
| Context Providers | src/context/ |
React context for notifications, stats, FPS |
| Selectors | src/state/ |
Derived state functions |
| Change Observers | src/state/onChangeAppState.ts |
Side-effects on state changes |
The AppState object is passed into tool contexts, giving tools access to conversation history, settings, and runtime state.
src/components/, ~140 components)Box, Text, useInput())src/components/design-system/src/screens/)Full-screen UI modes:
| Screen | Purpose |
|---|---|
REPL.tsx |
Main interactive REPL (the default screen) |
Doctor.tsx |
Environment diagnostics (/doctor) |
ResumeConversation.tsx |
Session restore (/resume) |
src/hooks/, ~80 hooks)Standard React hooks pattern. Notable categories:
useCanUseTool, src/hooks/toolPermission/useIDEIntegration, useIdeConnectionStatus, useDiffInIDEuseTextInput, useVimInput, usePasteHandler, useInputBufferuseSessionBackgrounding, useRemoteSession, useAssistantHistoryuseManagePlugins, useSkillsChangesrc/hooks/notifs/ (rate limits, deprecation warnings, etc.)src/schemas/)Zod v4-based schemas for all configuration:
src/migrations/)Handles config format changes between versions — reads old configs and transforms them to the current schema.
Claude Code runs on Bun (not Node.js). Key implications:
bun:bundle feature flags for dead-code elimination.js extensions (Bun convention)import { feature } from 'bun:bundle'
// Code inside inactive feature flags is completely stripped at build time
if (feature('VOICE_MODE')) {
const voiceCommand = require('./commands/voice/index.js').default
}
Notable flags:
| Flag | Feature |
|---|---|
PROACTIVE |
Proactive agent mode (autonomous actions) |
KAIROS |
Kairos subsystem |
BRIDGE_MODE |
IDE bridge integration |
DAEMON |
Background daemon mode |
VOICE_MODE |
Voice input/output |
AGENT_TRIGGERS |
Triggered agent actions |
MONITOR_TOOL |
Monitoring tool |
COORDINATOR_MODE |
Multi-agent coordinator |
WORKFLOW_SCRIPTS |
Workflow automation scripts |
Heavy modules are deferred via dynamic import() until first use:
src/services/analytics/)src/cost-tracker.ts)Tracks token usage and estimated cost per conversation turn. Accessible via the /cost command.
/doctor command)The Doctor.tsx screen runs environment checks: API connectivity, authentication, tool availability, MCP server status, and more.
Claude Code uses a single-threaded event loop (Bun/Node.js model) with:
isConcurrencySafe() to indicate if it can run in parallel with other tools