Deep dive into Claude Code CLI architecture — TypeScript, React/Ink, Bun
Disclaimer: This repository contains no proprietary source code. All content is original analysis, architectural diagrams, and commentary produced for educational and research purposes only. This project is not affiliated with or endorsed by Anthropic.
| Dimension | Detail |
|---|---|
| Language | TypeScript (strict mode) |
| Runtime | Bun |
| Terminal UI | React + Ink |
| CLI Framework | Commander.js |
| Validation | Zod v4 |
| Code Search | ripgrep (bundled) |
| Protocols | MCP (Model Context Protocol) + LSP |
| LLM Client | Anthropic SDK |
| Telemetry | OpenTelemetry |
| Feature Flags | GrowthBook |
| Codebase Size | ~1,900 files, 510K+ lines |
| Commands | 101 registered commands |
| Tools | 30+ built-in tools |
┌─────────────────────────────────────────────────────────┐
│ User Input │
│ Terminal / IDE Bridge / SDK │
└────────────────────────┬────────────────────────────────┘
│
┌────────────────────────▼────────────────────────────────┐
│ main.tsx │
│ Commander.js + React/Ink + parallel prefetch │
└────────────────────────┬────────────────────────────────┘
│
┌────────────┬───────────▼───────────┬────────────────────┐
│ Commands │ Query Engine │ Bridge System │
│ Registry │ (async generator │ (IDE integration, │
│ (101 cmds)│ streaming loop) │ SDK interface) │
└─────┬──────┴───────────┬───────────┴──────────┬─────────┘
│ │ │
┌─────▼──────┬───────────▼───────────┬──────────▼─────────┐
│ Permission │ Tool Orchestration │ Plugin + Skill │
│ System │ (30+ tools, Zod v4 │ System (MCP, │
│ (rules, │ validation, agent │ markdown-based │
│ hierarchy)│ spawning) │ plugins, skills) │
└────────────┴───────────────────────┴────────────────────┘
| Document | Description |
|---|---|
| docs/query-pipeline.md | LLM query loop, streaming, error recovery |
| docs/tool-system.md | Tool registry, validation, 30+ built-in tools |
| docs/permission-model.md | Hierarchical rule-based permission checking |
| docs/agent-orchestration.md | Multi-agent spawning, messaging, worktree isolation |
| docs/plugin-skill-system.md | Markdown-based plugins, skills, MCP integration |
| docs/prompt-engineering.md | System prompt assembly, feature-gated sections |
| docs/startup-performance.md | Parallel prefetch, lazy loading, dead code elimination |
Claude Code uses React with Ink to render its terminal UI. This is unusual for a CLI but makes sense given the requirements: the interface must render streaming LLM output, concurrent agent status, permission prompts, and tool progress — all simultaneously. React's declarative model and hooks-driven reactivity handle this naturally. When an agent completes or a permission prompt appears, the relevant component re-renders without manual terminal cursor management. Concurrent agent rendering (multiple sub-agents running in parallel) maps directly to concurrent React component trees.
Bun provides native TypeScript execution (no separate compile step), fast startup times critical for CLI responsiveness, and compile-time feature flags via bun:bundle that enable dead code elimination for different build targets (npm package vs. internal). The bundler produces a single executable with tree-shaken code paths.
The query loop (query()) is implemented as an async generator, yielding control at each step of the conversation cycle: sending messages, receiving streaming chunks, processing tool calls, checking permissions, and handling errors. This design enables non-blocking permission prompts (the generator pauses while waiting for user approval), recoverable errors (catch and resume the generator), and clean cancellation (return from the generator). The streaming nature of LLM responses maps naturally to the async iteration protocol.
sequenceDiagram
participant U as User
participant QE as QueryEngine
participant Q as query()
participant API as Claude API
participant TO as ToolOrchestration
participant PS as PermissionSystem
participant T as Tool.call()
U->>QE: submitMessage(text)
QE->>Q: query(messages)
Q->>API: stream request
API-->>Q: streaming chunks (text + tool_use)
Q->>TO: process tool_use block
TO->>PS: checkPermission(tool, args)
PS-->>TO: allow / deny / ask user
TO->>T: tool.call(args)
T-->>TO: ToolResult
TO-->>Q: append tool result to messages
Q->>API: continue conversation (with tool result)
API-->>Q: streaming response
Q-->>QE: final response
QE-->>U: rendered output
src/
main.tsx # Entry point — Commander.js + React/Ink + parallel prefetch
commands.ts # 101 registered commands
tools.ts # 30+ tool definitions
Tool.ts # Base tool interface and types
QueryEngine.ts # Message submission, conversation management
query.ts # Async generator query loop (streaming, tool calls)
context.ts # Conversation context assembly
cost-tracker.ts # Token usage and cost tracking
commands/ # Individual command implementations
tools/ # Tool implementations
BashTool/
FileReadTool/
FileEditTool/
AgentTool/
GlobTool/
GrepTool/
NotebookEditTool/
WebFetchTool/
...
components/ # ~140 React/Ink UI components
services/
api/ # Anthropic SDK integration
mcp/ # Model Context Protocol client
oauth/ # Authentication flows
compact/ # Conversation compaction
analytics/ # Telemetry and analytics
hooks/ # React hooks (state, effects, subscriptions)
bridge/ # IDE bridge (VS Code, JetBrains)
coordinator/ # Multi-agent coordination
plugins/ # Plugin loading and execution
skills/ # Skill system (markdown-based)
state/ # Application state management
memdir/ # Memory directory (persistent context)
schemas/ # Zod v4 schemas
utils/ # Shared utilities
This analysis is based on publicly accessible information including the published npm package, official Anthropic documentation, public discussions, and source maps that were briefly accessible in March 2026. All content in this repository is original commentary and analysis — no proprietary source code is reproduced.
This project is intended for educational and research purposes only. It is not affiliated with, endorsed by, or connected to Anthropic in any way.
Original analysis content in this repository is released under the MIT License.
Copyright (c) 2026.