Skip to main content
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, rendered to a terminal.

Core pipeline

┌─────────────┐    ┌──────────────┐    ┌────────────────┐
│  User Input │───▶│  CLI Parser  │───▶│  replLauncher  │
│  (stdin)    │    │ (Commander)  │    │  src/replLauncher.tsx │
└─────────────┘    └──────────────┘    └────────┬───────┘


                                       ┌────────────────┐
                                       │  Query Engine  │
                                       │ src/QueryEngine.ts │
                                       └────────┬───────┘

                          ┌─────────────────────┼──────────────────────┐
                          │                     │                      │
                          ▼                     ▼                      ▼
                  ┌──────────────┐    ┌──────────────────┐    ┌──────────────┐
                  │  LLM API     │    │  Tool Execution  │    │  AppState    │
                  │ (Anthropic)  │    │  Loop            │    │  Store       │
                  └──────────────┘    └──────────────────┘    └──────────────┘


                                       ┌────────────────┐
                                       │  Terminal UI   │
                                       │  React + Ink   │
                                       └────────────────┘

Six core systems

Entrypoint

src/main.tsx — CLI parsing via Commander.js with parallel prefetch side-effects on startup.

Query Engine

src/QueryEngine.ts (~46K lines) — streaming responses, tool-call loops, thinking mode, retry logic, token counting.

Tool System

src/Tool.ts + src/tools/ — every capability Claude can invoke, each with Zod schema, permission model, and UI component.

Command System

src/commands.ts + src/commands/ — user-facing slash commands (/commit, /review, /mcp, etc.).

State Management

src/state/ — React context + custom store pattern with selectors and change observers.

UI Layer

src/components/ (~140 components) + src/screens/ — React + Ink with Chalk styling and React Compiler.

Entrypoint

The CLI parser lives in src/main.tsx and is built with Commander.js (@commander-js/extra-typings). Startup is carefully ordered to maximize parallelism:
1

Parallel prefetch side-effects

Before any heavy imports, three side-effects fire in parallel:
  • profileCheckpoint('main_tsx_entry') — marks startup timing
  • startMdmRawRead() — fires MDM subprocesses (plutil/reg query) so they run concurrently with the remaining ~135ms of module evaluation
  • startKeychainPrefetch() — fires both macOS Keychain reads (OAuth + legacy API key) in parallel, saving ~65ms on every macOS startup
2

CLI parsing

Commander.js parses arguments and flags. Type-safe option definitions via @commander-js/extra-typings.
3

Initialization

src/entrypoints/init.ts handles config, telemetry, OAuth, and MDM policy setup.
4

React/Ink renderer

The Ink renderer is initialized and handed off to src/replLauncher.tsx, which mounts the REPL screen.

Initialization entrypoints

FileRole
src/entrypoints/cli.tsxCLI session orchestration — the main path from launch to REPL
src/entrypoints/init.tsConfig, telemetry, OAuth, MDM policy initialization
src/entrypoints/mcp.tsMCP server mode entrypoint (Claude Code as an MCP server)
src/entrypoints/sdk/Agent SDK — programmatic API for embedding Claude Code

Tool system

Every capability Claude can invoke is a tool. Each tool is self-contained with four elements:

Input schema

Zod validation schema describing the inputs the LLM must provide.

Permission model

Declares what requires user approval and whether it is concurrency-safe.

Execution logic

The actual implementation: file edits, bash commands, web search, etc.

UI components

React components that render the invocation and result in the terminal.
Tools are registered in src/tools.ts and discovered by the Query Engine during the tool-call loop. See the Tools Reference for the complete catalog.

Command system

User-facing slash commands (/commit, /review, /mcp, etc.) are defined in src/commands.ts and src/commands/. There are three command types:
TypeDescriptionExample
PromptCommandSends a formatted prompt to the LLM with injected tools/review, /commit
LocalCommandRuns in-process, returns plain text/cost, /version
LocalJSXCommandRuns in-process, returns React JSX/doctor, /install

Build system

Bun runtime

Claude Code runs on Bun (not Node.js). Key implications:
  • Native JSX/TSX support without a transpilation step
  • bun:bundle feature flags for dead-code elimination
  • ES modules with .js extensions (Bun convention)

Feature flags (dead-code elimination)

bun:bundle feature flags allow entire subsystems to be stripped at build time. Code inside an inactive flag is completely absent from the final binary:
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 feature flags:
FlagFeature
PROACTIVEProactive agent mode (autonomous actions)
KAIROSKairos subsystem
BRIDGE_MODEIDE bridge integration
DAEMONBackground daemon mode
VOICE_MODEVoice input/output
AGENT_TRIGGERSTriggered agent actions
MONITOR_TOOLMonitoring tool
COORDINATOR_MODEMulti-agent coordinator
WORKFLOW_SCRIPTSWorkflow automation scripts

Lazy loading

Heavy modules are deferred via dynamic import() until first use, keeping startup fast:
// Lazy: MessageSelector.tsx pulls React/ink; only needed for message filtering at query time
const messageSelector =
  (): typeof import('src/components/MessageSelector.js') =>
    require('src/components/MessageSelector.js')
Modules deferred this way include:
  • OpenTelemetry (~400KB)
  • gRPC (~700KB)
  • React/Ink components only needed at specific interaction points

Parallel prefetch pattern

The startup sequence fires network and I/O operations in parallel before they are needed, using a fire-and-forget pattern:
// src/main.tsx — fires before heavy module imports
startMdmRawRead()      // MDM policy: ~parallel with module eval
startKeychainPrefetch() // Keychain: saves ~65ms on macOS

Error handling and telemetry

Telemetry (src/services/analytics/)

ServicePurpose
GrowthBookFeature flags and A/B testing
OpenTelemetryDistributed tracing and metrics
Custom event trackingUsage analytics via logEvent()

Cost tracking (src/cost-tracker.ts)

Tracks token usage and estimated cost per conversation turn. Accessible via the /cost command.

Diagnostics (/doctor)

The Doctor.tsx screen runs environment checks: API connectivity, authentication, tool availability, MCP server status, and more.

Concurrency model

Claude Code uses a single-threaded event loop (Bun/Node.js model) with structured concurrency:
All file system, network, and subprocess operations use async/await. The event loop remains unblocked during I/O waits.
Ink’s React renderer handles UI updates concurrently with ongoing tool execution.
CPU-intensive tasks (gRPC, etc.) run in separate processes to avoid blocking the main event loop.
Each tool declares isConcurrencySafe() to indicate whether it can run in parallel with other tools. The Query Engine uses this to decide whether to execute tools sequentially or in parallel during multi-tool turns.

See also

Query Engine

Deep dive into the streaming response loop, tool-call lifecycle, and context management.

State Management & UI

AppState store, React context pattern, hooks catalog, and the design system.

Build docs developers (and LLMs) love