I Opened Claude Code's Source Code and Found 28 Design Patterns, a 4400-Line Bash Parser, and Zero Regrets
🔬

I Opened Claude Code's Source Code and Found 28 Design Patterns, a 4400-Line Bash Parser, and Zero Regrets

Tags
Software Development
AI
Research
Tech
Thought Experiments
Knowledge
AI summary
Published
April 2, 2026
Author
Cuong Nguyen

The Day I Decided to Read Someone Else's Homework

You know that feeling when you look at a successful person and think: "What is their secret?" Well, I had that feeling about Claude Code. Anthropic is now making $2.5 billion per year. Their AI coding agent is used by thousands of developers every day. So I did what any curious engineer would do.
I opened their source code. I read every file. I sent five AI agents to analyze it from five different angles.
What I found was not magic. It was engineering discipline. And also a 4,400-line bash parser written in pure TypeScript. But we will talk about that later.

How I Did This Analysis

I created a team of five AI agents. Each agent looked at the same codebase from a different perspective:
  1. The Architect — looked at the overall system structure
  1. The Pattern Hunter — found design patterns and algorithms
  1. The Security Guard — analyzed the permission and safety systems
  1. The Performance Engineer — studied speed and cost optimization
  1. The Innovation Scout — explored unique features and product decisions
Think of it like five doctors examining the same patient. One checks the heart, one checks the brain, one checks the bones. Together, they see the full picture.
This is also a good lesson for life: when you face a complex problem, do not try to understand everything at once. Look at it from different angles. Each angle will show you something the others missed.

Part 1: The Architecture — How the House is Built

The Big Picture

Claude Code is a modular monolith with a microkernel design. What does that mean in simple words?
Imagine a house. The foundation and walls are one solid structure (the monolith). But the electrical system, the plumbing, and the heating are all separate modules that plug into the walls (the microkernel). You can replace the heating system without destroying the walls.
The tech stack:
  • React Ink for the terminal user interface (yes, React in a terminal!)
  • TypeScript for everything
  • Custom state management (they built their own, similar to Zustand)
  • Bun as the JavaScript runtime

Why React in a Terminal?

This was my first surprise. Most CLI tools use simple text output. Claude Code uses React to render its terminal interface.
Why? Because the UI is complex. It has:
  • Permission request dialogs
  • Streaming text with syntax highlighting
  • Vim-mode editing (490 lines of state machine code!)
  • Multiple panels and tabs
  • Voice input controls
React's component model makes all of this manageable. The same way React makes complex web UIs manageable.
Life parallel: Sometimes the "unusual" choice is the correct choice. Everyone expects CLI tools to be simple. But Claude Code's UI needs are complex, so they chose the tool that fits the need, not the tool that fits the expectation.

The Core Loop

The heart of Claude Code is a simple loop:
  1. User sends a message
  1. Message goes to the QueryEngine
  1. QueryEngine sends it to Claude API
  1. Claude responds with text or tool calls
  1. StreamingToolExecutor runs the tools
  1. Results go back to step 3
  1. Repeat until Claude has nothing more to do
This loop is simple to describe but very hard to build well. The details are where the engineering lives.

Part 2: The 28 Design Patterns — A Catalog of Good Decisions

This is where I started taking notes very fast. The codebase uses 28 identifiable design patterns. Here are the most interesting ones:

Strategy Pattern — 60+ Tools, One Interface

Every tool (Bash, FileEdit, WebSearch, AgentTool, etc.) implements the same Tool interface. The model says "use this tool" and the system just calls tool.call(). No giant switch statement. No if-else chain.
This is textbook Strategy Pattern. But the implementation has a clever detail: the buildTool() factory function adds fail-closed defaults.
isConcurrencySafe: false (cannot run with other tools) isReadOnly: false (might modify files)
Every new tool starts with maximum restrictions. You must explicitly mark it as safe. This is the opposite of most software, where new features start with no restrictions and you add them later.
Life lesson: Start with restrictions, then loosen them. Not the other way around. This applies to permissions, budgets, and even habits. Start strict, then adjust.

Readers-Writer Lock — Parallel But Safe

The StreamingToolExecutor uses a pattern from database systems: multiple "readers" can work at the same time, but a "writer" needs exclusive access.
In practice: five FileRead calls can run in parallel. But one FileEdit call blocks everything else.
This is why Claude Code feels fast when it is reading your codebase but takes turns when editing files.

WeakRef Abort Tree — Memory-Safe Cancellation

This one surprised me. When you cancel a query, all running tools must stop. But if a child tool finishes before the cancel message arrives, its cleanup code must not interfere with the next query.
The solution: a tree of AbortController objects connected with WeakRef. When a child is garbage collected, the parent listener is automatically cleaned up. No memory leaks. No dangling references.
I have been programming for years and I have never seen this pattern in production code before.

Generation Counter — Solving the Stale Cleanup Problem

Imagine this scenario:
  1. Query A starts
  1. User cancels Query A
  1. Query B starts
  1. Query A's cleanup code finally runs
  1. Query A's cleanup accidentally cleans up Query B's state
The solution is elegant: each query gets a generation number. When cleanup runs, it checks if the generation still matches. If not, it does nothing.
tryStart(): ++generation; return generation end(gen): if (gen !== generation) return false // stale!
No locks. No mutexes. Just a counter.
Life lesson: Sometimes the simplest solution is a counter. Not every problem needs a complex framework.

AsyncGenerator for Retry — Errors as a Stream

The retry system (withRetry) does not just retry and return. It uses an AsyncGenerator to yield error notifications as they happen. The caller can show "Retrying... attempt 3 of 10" in real time.
This is an unusual use of generators. Most code uses them for data streaming. Here, they stream error events.

Part 3: Security — 2,600 Lines of Paranoia (The Good Kind)

The security system is the most impressive part of the codebase. And also the most educational.

Defense in Depth — Six Layers

Claude Code does not rely on one security check. It has six independent layers:
Layer
What it does
Attack it prevents
Permission Cascade
7-source priority hierarchy
Privilege escalation
Bash Security
20+ independent validators
Command injection
Read-Only Validation
Flag-level allowlist for 30 commands
Write disguised as read
OS Sandbox
bubblewrap (Linux) / sandbox-exec (macOS)
File system escape
Git Repo Protection
Post-command file scrubbing
RCE via git hooks
Settings Protection
All config files are deny-listed for writes
Configuration tampering
If one layer fails, the others still protect you.

The 4,400-Line Bash Parser

Yes, you read that correctly. Claude Code includes a full recursive descent parser for bash written in pure TypeScript. It produces tree-sitter-compatible AST (Abstract Syntax Tree) nodes.
Why? Because security analysis of bash commands requires understanding the command structure. Regular expressions are not enough. A command like find . -exec rm {} \; looks dangerous if you only check for rm, but it might be perfectly safe in context.
The parser has two safety limits:
  • 50 millisecond timeout — prevents parsing attacks
  • 50,000 node budget — prevents memory attacks
Life lesson: Sometimes "good enough" is not good enough. When the cost of failure is high (security), invest in the correct solution even if it costs 4,400 lines of code.

My Favorite Security Detail

Every security-sensitive line in the codebase has a // SECURITY: comment explaining which attack it prevents. Many reference specific HackerOne bug reports.
This is not just good engineering. This is institutional knowledge preservation. When a new developer joins the team three years later, they will understand why each check exists.

Part 4: Performance — How to Save 250,000 API Calls Per Day

This section contains the most practical lessons. If you are building any product that uses LLM APIs, read this carefully.

Bypass Your Own SDK

Claude Code does not use the official SDK's streaming helper (BetaMessageStream). Why? Because that helper re-parses accumulated JSON on every small update, creating O(n-squared) performance.
Instead, they use the raw stream and parse JSON only once, at the end of each content block.
The comment in the code says it clearly:
"Use raw stream instead of BetaMessageStream to avoid O(n-squared) partial JSON parsing"
This is a reminder: always profile your dependencies. The "official" way is not always the fastest way.

The Hybrid Token Counter

Counting tokens is expensive — it requires an API call. But you need to know how many tokens you have used to manage the context window.
The solution: use the API's exact token count as an "anchor point" and then estimate the rest using a simple formula:
tokens = characters / 4
For JSON content, use characters / 2 because JSON has more single-character tokens.
This hybrid approach gives good enough accuracy without extra API calls.

The Circuit Breaker That Saved 250,000 API Calls Per Day

When the conversation gets too long, Claude Code tries to auto-compact it (summarize old messages). But sometimes this fails. And sometimes it fails again. And again.
Without a circuit breaker, these failed attempts waste API calls forever. Data showed that some sessions had 3,272 consecutive failures.
The fix: after 3 consecutive failures, stop trying. This simple rule saved approximately 250,000 wasted API calls per day.
Life lesson: Not every failure deserves a retry. Sometimes the best response to repeated failure is to stop and accept the situation. This is true for API calls and also for relationships.

Foreground vs Background Priorities

When the API is overloaded (HTTP 529), Claude Code retries the user's main query. But it does not retry background tasks like generating titles or summaries.
Why? Because each retry during a capacity crisis creates 3-10 times more load on the gateway. Background retries make the problem worse for everyone.

Part 5: Innovation — The Secret Sauce

Skills as Configuration

Claude Code's skill system is one of the most creative solutions I have seen. A "skill" is just a Markdown file with YAML frontmatter. That is it. No code. No compilation. No deployment.
You write instructions in Markdown, put the file in a directory, and Claude Code discovers and uses it automatically.
This turns "extending an AI agent" from a programming task into a writing task. Anyone who can write clear instructions can create a skill.

Git Worktree Isolation

When Claude Code runs multiple agents in parallel, each agent gets its own git worktree. This is a git feature that creates a separate working directory linked to the same repository.
Result: 5 to 30 agents can edit files simultaneously without conflicts. Each agent works in its own directory. When they finish, the results are merged.

The Memdir System — AI Memory

Claude Code has a memory system that remembers things about you across sessions. But it does not just store raw text. It categorizes memories into four types: user preferences, feedback, project context, and reference materials.
When Claude needs to remember something, it sends a side query to a smaller model (Sonnet) to find relevant memories. This is like having a personal assistant who keeps organized notes and searches them for you.

What Makes This a $2.5B Product?

After reading the entire codebase, I believe the competitive advantage is not any single feature. It is the combination of engineering quality across all layers:
  1. Security that references specific bug reports in code comments
  1. Performance optimization that saves 250K API calls per day
  1. A plugin system (MCP) that works with 4 transport types
  1. A skill system that turns behavior extension into a writing task
  1. Multi-agent orchestration with git-level isolation
  1. A 28-pattern design that makes the codebase maintainable at scale
No single feature is impossible to copy. But doing ALL of them well, at the same time, is very hard.

What I Learned (Beyond Code)

Reading someone else's excellent code is like visiting a master chef's kitchen. You learn not just recipes, but how to organize your workspace.

10 Lessons You Can Use Today

  1. Start restricted, then loosen — Every new tool defaults to "unsafe until proven safe"
  1. Profile your dependencies — The official SDK was the bottleneck
  1. Add circuit breakers to every retry loop — 3 failures is enough
  1. Comment WHY, not WHAT// SECURITY: prevents HackerOne #3543050 is better than // check input
  1. Use generation counters for stale state — Simpler than locks
  1. Separate foreground and background priorities — Do not let background tasks make outages worse
  1. Markdown is a programming language — Skills-as-configuration is brilliant
  1. WeakRef is underused — Perfect for cleanup hierarchies
  1. Hybrid estimation beats exact calculation — Good enough accuracy, zero extra cost
  1. Defense in depth, always — One security layer is never enough

Final Thought

There is a Vietnamese saying: "Đi một ngày đàng, học một sàng khôn" — Travel one day on the road, learn a basket of wisdom.
I did not travel anywhere. I just read source code for a few hours. But the basket is full.
The best engineers do not have secret tricks. They have discipline. They write security comments. They add circuit breakers. They measure before they optimize. They choose boring solutions that work over exciting solutions that break.
And sometimes, they write a 4,400-line bash parser. Because the job requires it.

This analysis was performed by a team of 5 AI agents, each exploring a different perspective of the Claude Code v2.1.88 source code. Total patterns identified: 28. Total security layers: 6. Total life lessons: more than expected.