Execution Flow in Detail
What makes Claude Code's execution flow truly special is how it combines real-time responsiveness with sophisticated coordination between AI, tools, and UI. Unlike many AI assistants that follow a simple request-response pattern, Claude Code operates as a continuous generator-driven stream where each step produces results immediately, without waiting for the entire process to complete.
At my core, I use async generators throughout the system. This pattern allows me to start producing results as soon as I have them, rather than waiting for the entire operation to complete. For developers familiar with modern JavaScript/TypeScript, this is similar to how an async*
function can yield
values repeatedly before completing.
Let's follow a typical query from the moment you press Enter to the final response:
%%{init: {'theme':'neutral', 'themeVariables': { 'primaryColor': '#5D8AA8', 'primaryTextColor': '#fff', 'primaryBorderColor': '#1F456E', 'lineColor': '#1F456E', 'secondaryColor': '#006400', 'tertiaryColor': '#fff'}}}%% flowchart TB classDef primary fill:#5D8AA8,stroke:#1F456E,stroke-width:2px,color:white; classDef secondary fill:#006400,stroke:#004000,stroke-width:2px,color:white; classDef highlight fill:#FF7F50,stroke:#FF6347,stroke-width:2px,color:white; A["User Input"] --> B["Input Processing"] B --> C["Query Generation"] C --> D["API Interaction"] D --> E["Tool Use Handling"] E -->|"Tool Results"| C D --> F["Response Rendering"] E --> F class A,B,C,D primary class E highlight class F secondary
1. User Input Capture
Everything begins with user input. When you type a message and press Enter, several critical steps happen immediately:
AbortController
that can terminate any operation anywhere in the execution flow. This clean cancellation mechanism means you can press Ctrl+C at any point and have the entire process terminate gracefully.
%%{init: {'theme':'neutral', 'themeVariables': { 'primaryColor': '#5D8AA8', 'primaryTextColor': '#fff', 'primaryBorderColor': '#1F456E', 'lineColor': '#1F456E', 'secondaryColor': '#006400', 'tertiaryColor': '#fff'}}}%% flowchart TD classDef userAction fill:#FF7F50,stroke:#FF6347,stroke-width:2px,color:white; classDef component fill:#5D8AA8,stroke:#1F456E,stroke-width:2px,color:white; classDef function fill:#006400,stroke:#004000,stroke-width:2px,color:white; A["🧑💻 User types and hits Enter"] --> B["PromptInput.tsx captures input"] B --> C["onSubmit() is triggered"] C --> D["AbortController created for<br> potential cancellation"] C --> E["processUserInput() called"] class A userAction class B component class C,D,E function
2. Input Processing
Claude Code now evaluates what kind of input you've provided. There are three distinct paths:
- Bash commands (prefixed with
!
) - These are sent directly to the BashTool for immediate execution - Slash commands (like
/help
or/compact
) - These are processed internally by the command system - Regular prompts - These become AI queries to Claude
%%{init: {'theme':'neutral', 'themeVariables': { 'primaryColor': '#5D8AA8', 'primaryTextColor': '#fff', 'primaryBorderColor': '#1F456E', 'lineColor': '#1F456E', 'secondaryColor': '#006400', 'tertiaryColor': '#fff'}}}%% flowchart TD classDef function fill:#006400,stroke:#004000,stroke-width:2px,color:white; classDef decision fill:#FF7F50,stroke:#FF6347,stroke-width:2px,color:white; classDef action fill:#5D8AA8,stroke:#1F456E,stroke-width:2px,color:white; A["processUserInput()"] --> B{"What type of input?"} B -->|"Bash command (!)"| C["Execute with BashTool"] B -->|"Slash command (/)"| D["Process via<br>getMessagesForSlashCommand()"] B -->|"Regular prompt"| E["Create user message"] C --> F["Return result messages"] D --> F E --> F F --> G["Pass to onQuery()<br>in REPL.tsx"] class A,C,D,E,F,G function class B decision
3. Query Generation
For standard prompts that need Claude's intelligence, the system now transforms your input into a fully-formed query with all necessary context:
- The system prompt (Claude's instructions and capabilities)
- Contextual data (about your project, files, and history)
- Model configuration (which version of Claude, token limits, etc.)
This query preparation phase is critical because it's where Claude Code determines what information and tools to provide to the AI model. Context management is carefully optimized to prioritize the most relevant information while staying within token limits.
%%{init: {'theme':'neutral', 'themeVariables': { 'primaryColor': '#5D8AA8', 'primaryTextColor': '#fff', 'primaryBorderColor': '#1F456E', 'lineColor': '#1F456E', 'secondaryColor': '#006400', 'tertiaryColor': '#fff'}}}%% flowchart TD classDef function fill:#006400,stroke:#004000,stroke-width:2px,color:white; classDef data fill:#5D8AA8,stroke:#1F456E,stroke-width:2px,color:white; classDef core fill:#8A2BE2,stroke:#4B0082,stroke-width:2px,color:white; A["onQuery() in REPL.tsx"] --> B["Collect system prompt"] A --> C["Gather context"] A --> D["Get model information"] B & C & D --> E["Call query() in query.ts"] class A function class B,C,D data class E core
4. Generator System Core
Now we reach the heart of Claude Code's architecture: the generator system core. This is where the real magic happens:
query()
function is implemented as an async generator
. This means it can start streaming Claude's response immediately, token by token, without waiting for the complete response. You'll notice this in the UI where text appears progressively, just like in a conversation with a human.
The API interaction is highly sophisticated:
- First, the API connection is established with the complete context prepared earlier
- Claude's responses begin streaming back immediately as they're generated
- The system monitors these responses to detect any "tool use" requests
- If Claude wants to use a tool (like searching files, reading code, etc.), the response is paused while the tool executes
- After tool execution, the results are fed back to Claude, which can then continue the response
This architecture enables a fluid conversation where Claude can actively interact with your development environment, rather than just responding to your questions in isolation.
%%{init: {'theme':'neutral', 'themeVariables': { 'primaryColor': '#5D8AA8', 'primaryTextColor': '#fff', 'primaryBorderColor': '#1F456E', 'lineColor': '#1F456E', 'secondaryColor': '#006400', 'tertiaryColor': '#fff'}}}%% flowchart TD classDef core fill:#8A2BE2,stroke:#4B0082,stroke-width:2px,color:white; classDef api fill:#FF7F50,stroke:#FF6347,stroke-width:2px,color:white; classDef decision fill:#FFD700,stroke:#DAA520,stroke-width:2px,color:black; classDef function fill:#006400,stroke:#004000,stroke-width:2px,color:white; A["query() function"] --> B["Format system prompt<br>with context"] B --> C["Call Claude API via<br>querySonnet()"] C --> D["Stream initial response"] D --> E{"Contains tool_use?"} E -->|"No"| F["Complete response"] E -->|"Yes"| G["Process tool use"] class A,B core class C,D api class E decision class F,G function
5. Tool Use Handling
When Claude decides it needs more information or wants to take action on your system, it triggers tool use. This is one of the most sophisticated parts of Claude Code:
What makes Claude Code's tool system particularly powerful is its parallel execution capability:
- The system first determines whether the requested tools can run concurrently
- Read-only tools (like file searches and reads) are automatically parallelized
- System-modifying tools (like file edits) run serially to prevent conflicts
- All tool operations are guarded by the permissions system
- After completion, results are reordered to match the original sequence for predictability
Perhaps most importantly, the entire tool system is recursive. When Claude receives the results from tool execution, it continues the conversation with this new information. This creates a natural flow where Claude can:
- Ask a question
- Read files to find the answer
- Use the information to solve a problem
- Suggest and implement changes
- Verify the changes worked
...all in a single seamless interaction.
%%{init: {'theme':'neutral', 'themeVariables': { 'primaryColor': '#5D8AA8', 'primaryTextColor': '#fff', 'primaryBorderColor': '#1F456E', 'lineColor': '#1F456E', 'secondaryColor': '#006400', 'tertiaryColor': '#fff'}}}%% flowchart TD classDef process fill:#5D8AA8,stroke:#1F456E,stroke-width:2px,color:white; classDef decision fill:#FFD700,stroke:#DAA520,stroke-width:2px,color:black; classDef function fill:#006400,stroke:#004000,stroke-width:2px,color:white; classDef permission fill:#FF7F50,stroke:#FF6347,stroke-width:2px,color:white; classDef result fill:#8A2BE2,stroke:#4B0082,stroke-width:2px,color:white; A["🔧 Process tool use"] --> B{"Run concurrently?"} B -->|"Yes"| C["runToolsConcurrently()"] B -->|"No"| D["runToolsSerially()"] C & D --> E["Check permissions<br>with canUseTool()"] E -->|"✅ Approved"| F["Execute tools"] E -->|"❌ Rejected"| G["Return rejection<br>message"] F --> H["Collect tool<br>responses"] H --> I["Recursive call to query()<br>with updated messages"] I --> J["Continue conversation"] class A process class B decision class C,D,F,I function class E permission class G,H,J result
6. Async Generators
The entire Claude Code architecture is built around async generators. This fundamental design choice powers everything from UI updates to parallel execution:
async function*
in TypeScript/JavaScript) allow a function to yield multiple values over time asynchronously. They combine the power of async/await
with the ability to produce a stream of results.
Claude Code's generator system provides several key capabilities:
- Real-time feedback - Results stream to the UI as they become available, not after everything is complete
- Composable streams - Generators can be combined, transformed, and chained together
- Cancellation support - AbortSignals propagate through the entire generator chain, enabling clean termination
- Parallelism - The
all()
utility can run multiple generators concurrently while preserving order - Backpressure handling - Slow consumers don't cause memory leaks because generators naturally pause production
The most powerful generator utility is all()
, which enables running multiple generators concurrently while preserving their outputs. This is what powers the parallel tool execution system, making Claude Code feel responsive even when performing complex operations.
%%{init: {'theme':'neutral', 'themeVariables': { 'primaryColor': '#5D8AA8', 'primaryTextColor': '#fff', 'primaryBorderColor': '#1F456E', 'lineColor': '#1F456E', 'secondaryColor': '#006400', 'tertiaryColor': '#fff'}}}%% flowchart LR classDef concept fill:#8A2BE2,stroke:#4B0082,stroke-width:2px,color:white; classDef file fill:#5D8AA8,stroke:#1F456E,stroke-width:2px,color:white; classDef function fill:#006400,stroke:#004000,stroke-width:2px,color:white; classDef result fill:#FF7F50,stroke:#FF6347,stroke-width:2px,color:white; A["⚙️ Async generators"] --> B["utils/generators.ts"] B --> C["lastX(): Get last value"] B --> D["all(): Run multiple<br>generators concurrently"] C & D --> E["Real-time streaming<br>response handling"] class A concept class B file class C,D function class E result
7. Response Processing
The final phase of the execution flow is displaying the results to you in the terminal:
The response processing system has several key features:
- Normalization - All responses, whether from Claude or tools, are normalized into a consistent format
- Categorization - Messages are divided into "static" (persistent) and "transient" (temporary, like streaming previews)
- Chunking - Large outputs are broken into manageable pieces to prevent terminal lag
- Syntax highlighting - Code blocks are automatically syntax-highlighted based on language
- Markdown rendering - Responses support rich formatting through Markdown
This final step transforms raw response data into the polished, interactive experience you see in the terminal.
%%{init: {'theme':'neutral', 'themeVariables': { 'primaryColor': '#5D8AA8', 'primaryTextColor': '#fff', 'primaryBorderColor': '#1F456E', 'lineColor': '#1F456E', 'secondaryColor': '#006400', 'tertiaryColor': '#fff'}}}%% flowchart TD classDef data fill:#5D8AA8,stroke:#1F456E,stroke-width:2px,color:white; classDef process fill:#006400,stroke:#004000,stroke-width:2px,color:white; classDef ui fill:#FF7F50,stroke:#FF6347,stroke-width:2px,color:white; A["📊 Responses from generator"] --> B["Collect in messages state"] B --> C["Process in REPL.tsx"] C --> D["Normalize messages"] D --> E["Categorize as<br>static/transient"] E --> F["Render in UI"] class A,B data class C,D,E process class F ui
Key Takeaways
The execution flow of Claude Code illustrates several innovative patterns worth incorporating into your own agentic systems:
-
Streaming first - Use async generators everywhere to provide real-time feedback and cancellation support.
-
Recursive intelligence - Allow the AI to trigger tool use, receive results, and continue with that new information.
-
Parallel where possible, serial where necessary - Automatically parallelize read operations while keeping writes serial.
-
Permission boundaries - Create clear separation between read-only and system-modifying operations with appropriate permission gates.
-
Composable primitives - Build with small, focused utilities that can be combined in different ways rather than monolithic functions.
These patterns create a responsive, safe, and flexible agent architecture that scales from simple tasks to complex multi-step operations.