Systematic methodology for reading and understanding large codebases efficiently. Use when (1) Understanding a new or unfamiliar codebase quickly, (2) Preparing to modify or extend existing code safely, (3) Debugging complex issues requiring deep code understanding, (4) Onboarding new team members to a codebase, (5) Performing code audits or security reviews, (6) Refactoring legacy code with confidence, (7) Creating documentation for existing systems, (8) Tracing execution flows and data transformations
A systematic approach to understanding large codebases efficiently: read to modify safely, not to memorize everything.
Goal-oriented reading: Always start with a concrete objective (fix bug, add feature, debug issue, security audit). Without a goal, you'll get lost in details.
Success criteria: You can explain the execution flow and modify code confidently, not that you've read every file.
When documenting your understanding, use this structure:
code-reading/
├── README.md # Index and progress tracking
├── code-reading.md # Main framework (methodology + findings + terminology)
├── architecture.md # C4 architecture map (Level 1-4)
├── api-flow.md # Execution flow tracing
└── key-modules.md # Detailed module analysis
Progressive disclosure:
Terminology section:
code-reading.md (e.g., section 9)Start with a concrete, one-sentence objective:
First hour priority:
Why: Running code transforms reading from guessing to verification.
Draw a rough map from far to near (no need to be perfect):
Level 1: System Context - Who uses it? What external dependencies? Level 2: Containers - What are the deployable units? (services, databases, workers) Level 3: Components - What are the key components within one container?
You don't need beautiful diagrams - just enough to navigate: where's the entry point, how does data flow, where are the boundaries?
Instead of reading modules, read one execution path:
Strongly recommended: Use a debugger, add logging, set breakpoints to walk through once.
If code is old/hard to test, write characterization tests first - record current behavior, then refactor under protection.
Define your reading task:
Write a one-sentence goal that describes what you want to achieve:
Avoid: Reading without purpose or starting from directory trees.
Priority order (first hour):
Verify: Model files exist, tests run, examples work.
Level 1: System Context
Level 2: Containers
Level 3: Components
Output: A rough map that answers:
Find the entry point:
main(), route handlers, controllersmain(), command parsersTrace one complete path:
Document the flow: Write down the execution path as you trace it.
Existing tests:
Missing tests:
When you see "weird code":
Don't dismiss it immediately - ask: What historical problem is this solving?
Commands:
git blame -w -- path/to/file # Who changed this and when?
git log -p -- path/to/file # Full change history
git log --grep="keyword" # Find related commits
git show <commit-hash> # View specific change
What to look for:
Code search:
rg "keyword" -n . # Ripgrep (faster than grep)
git grep "keyword" # Git-optimized search
rg "main\(" . # Find entry points
rg "TODO|FIXME" . # Find todos
Git tools:
git log --graph --oneline --all # Visual history
git log --follow -- path/to/file # File rename tracking
git diff HEAD~5 HEAD # Compare versions
Language-specific tools:
cargo tree, cargo clippy, cargo docpytest, mypy, pylintnpm list, eslint, tscCritical for understanding: Build a living terminology glossary from day 1, not as an afterthought.
Why it matters:
When to build:
What to include:
Organization:
Example structure:
## Terminology Glossary
### Domain-Specific Terms
- **Detection (检测)**: Locating text regions in images
- **Implementation**: `src/det.rs`
- **Related**: Recognition, NMS, DB
- **See**: `api-flow.md` section 4.1
### Data Structures
- **`Mat`**: Image matrix abstraction
- **Implementation**: `src/image_impl.rs`
- **Purpose**: Unified image representation for Pure Rust and OpenCV backends
### Algorithms
- **NMS (Non-Maximum Suppression)**: Algorithm for filtering overlapping boxes
- **Implementation**: `src/geometry.rs::nms()`
- **Related**: IOU (Intersection over Union)
Tools for term extraction:
# Extract acronyms (all caps, 2-5 chars)
rg "\b[A-Z]{2,5}\b" README.md docs/ | sort -u
# Extract struct/enum/trait names
rg "^(pub )?(struct|enum|trait|type) \w+" src/ -o | sort -u
# Find config-related terms
rg "Config.*\{|struct \w+Config" src/
Maintenance checklist:
Problem: Reading files alphabetically or by directory structure.
Solution: Start with a concrete task. Even if it's "understand how X works," make it specific.
Problem: Deep-diving into every module before understanding the flow.
Solution: First trace one complete execution path. Then dive into specific modules as needed.
Problem: Treating tests as optional or skipping them.
Solution: Tests are the most reliable documentation. Read them first. If missing, write characterization tests.
Problem: Seeing "weird code" and assuming it's wrong.
Solution: Use git blame and git log to understand context. Code exists for reasons, even if not obvious.
Problem: Encountering acronyms (CTC, CLS, DB, NMS) or domain terms (Detection vs Recognition) and assuming you'll remember what they mean later. Repeatedly looking up the same terms.
Solution: Build a terminology glossary from day 1. Collect terms as you encounter them, enrich with context as understanding deepens. Cross-reference terms throughout documentation. Treat it as a living document, not a one-time task.
You've successfully understood a codebase when:
✅ You can explain the main execution flow from entry to exit ✅ You can locate where specific functionality is implemented ✅ You can trace data transformations through the system ✅ You can identify where to make changes for your goal ✅ You can explain architectural decisions (even if you'd do differently) ✅ You have a comprehensive terminology glossary that helps navigate the codebase ✅ You can explain any domain-specific term in one sentence ✅ You rarely need to re-lookup the same term ✅ You feel confident modifying code without breaking things
Not required:
"I don't know where to start" → Define a concrete goal. Even "understand how user authentication works" is better than "understand everything."
"The codebase is too large" → Focus on your goal. Trace one execution path. Ignore unrelated modules.
"I can't find the entry point"
→ Look for main(), route definitions, or public API functions. Use code search tools.
"The code doesn't make sense" → Use Git history to understand why it's written this way. Check tests for usage examples.
"There are no tests" → Write characterization tests. Record current behavior before modifying.
"I keep forgetting what CTC/CLS/DB means" → Build a terminology glossary. Start early, collect terms as you encounter them. Include definitions, context, code references, and relationships. Cross-reference throughout documentation.
"The domain terms are confusing" → Don't just look them up once. Document them with context, usage examples, and relationships to other terms. Classify by domain and abstraction level. Update as understanding deepens.
For detailed methodology and examples, see:
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer