Architectural layers
main.tsx — CLI entrypoint
main.tsx is the top of the call stack. It uses Commander.js to parse flags and subcommands, then mounts the React/Ink renderer for the interactive terminal UI. Two startup optimizations fire as side effects before any heavy module is evaluated:
QueryEngine — LLM engine
QueryEngine.ts (~46 000 lines) owns the conversation loop. It sends messages to the Anthropic API, streams the response, detects tool-use blocks, routes each tool call through the permission layer and tool system, and feeds results back into the next API call. It also handles:
- Streaming token accounting and cost tracking
- Extended thinking mode configuration
- Automatic retry on transient API errors
- Context compression triggers (
/compact) - Session transcript persistence
Tool system — src/tools/
Each tool is a self-contained module with an input schema, a permission declaration, and an execution function. TheQueryEngine calls a tool by name; the tool system resolves the implementation, validates the input with Zod, and runs it. See Tool system for details.
Permission layer — src/hooks/toolPermission/
Before any tool executes, the permission layer is consulted. Depending on the configured mode, it either prompts the user interactively, auto-approves, or rejects. See Permission model for details.Service layer — src/services/
Stateless integrations that tools and the engine call out to:| Service | Responsibility |
|---|---|
api/ | Anthropic API client, streaming, file uploads |
mcp/ | Model Context Protocol server connections |
lsp/ | Language Server Protocol manager |
oauth/ | OAuth 2.0 authentication flow |
analytics/ | GrowthBook feature flags and event logging |
compact/ | Conversation context compression |
extractMemories/ | Automatic memory extraction at turn end |
teamMemorySync/ | Team memory synchronization |
Tech stack
| Category | Technology |
|---|---|
| Runtime | Bun |
| Language | TypeScript (strict mode) |
| Terminal UI | React + Ink |
| CLI parsing | Commander.js (extra-typings) |
| Schema validation | Zod v4 |
| Code search | ripgrep (via GrepTool) |
| Protocols | MCP SDK, LSP |
| LLM API | Anthropic SDK |
| Telemetry | OpenTelemetry + gRPC (lazily loaded) |
| Feature flags | GrowthBook |
| Auth | OAuth 2.0, JWT, macOS Keychain |
Performance patterns
Parallel prefetch at startup
main.tsx fires MDM settings reads and Keychain prefetches as parallel side effects before Commander.js begins parsing. This means credentials and policy settings are ready by the time the first API call is made, with no sequential wait.
Lazy loading of heavy modules
OpenTelemetry (~400 KB) and gRPC (~700 KB) are deferred via dynamicimport() until the code path that needs them actually runs. They are never loaded in sessions that don’t use telemetry.
Agent swarms
Sub-agents are spawned viaAgentTool, with src/coordinator/ handling multi-agent orchestration. TeamCreateTool enables team-level parallel work across independent workstreams. See Agent swarms.
Feature flags
Claude Code uses Bun’sbun:bundle API for compile-time dead code elimination. Inactive features are stripped entirely from the production bundle — they add zero runtime overhead.
| Flag | Feature |
|---|---|
PROACTIVE | Proactive (background) agent mode |
KAIROS | Assistant/Kairos mode with daily log memory |
BRIDGE_MODE | IDE extension bridge (VS Code, JetBrains) |
DAEMON | Background daemon process |
VOICE_MODE | Voice input support |
AGENT_TRIGGERS | Scheduled and remote agent triggers |
MONITOR_TOOL | MonitorTool for agent observation |
Feature flags are resolved at build time. You cannot enable a flagged feature at runtime unless it was included in the build you are running.
Related pages
Tool system
How tools are defined, registered, and invoked inside the query loop.
Permission model
How every tool invocation is checked before execution.
Memory and context
Persistent memory, CLAUDE.md files, and context management.
MCP servers
Connecting external tools via the Model Context Protocol.