The hardest part of a new codebase is often deciding where to look. A directory tree gives you hundreds of possible starting points and very little reason to choose one. The way through is to begin with a behavior, then let the code show you which files matter.
You are building a working model: enough understanding to explain a path, make a change carefully, or ask the next useful question. You do not need a complete inventory before you can begin.
Start with something you can observe
Choose a concrete behavior. A command prints a result. A button opens a document. A request returns an error. A background job retries a failed operation.
Phrase your question in terms of that behavior:
What happens between selecting a file and seeing its contents in the editor?
This question gives your investigation an entry point and an end point. It also gives you a way to notice irrelevant detail. The application’s update mechanism might be interesting, but it probably does not explain how a selected file is loaded.
If you can run the project safely, reproduce the behavior before reading deeply. Record the input and the result. If you cannot run it, say that your model is based on source evidence and keep runtime assumptions visible.
Find the entry point
Search for a distinctive string, a handler name, a route, or a command definition. Tests can also expose the entry point more clearly than production code does.
For a file reader, you might discover:
async function selectFile(path: string) {
const document = await openDocument(path);
tabs.open(document);
context.setActiveDocument(document);
}
This small function already suggests three responsibilities: loading a document, displaying it, and updating the active context. Treat those as hypotheses until you inspect the called functions.
Follow one call at a time. Keep the entry point open so you can return to the original question instead of drifting through unrelated definitions.
Track the data, not only the calls
A call graph tells you which functions connect. Understanding also requires knowing what moves between them.
For each important value, ask:
- Where does it come from?
- Who validates or transforms it?
- Which component owns it after this step?
- Does it represent current state, cached state, or a historical snapshot?
In the example, path might be a workspace-relative path or an absolute path. That distinction affects validation and file access. The returned document might be immutable content or a shared object that other parts of the application can update.
Read the types and constructors that establish those facts. A familiar variable name is not sufficient evidence.
Inspect one failure path
Once you understand the successful path, choose a plausible failure: the file disappears, parsing fails, the operation is cancelled, or another selection arrives before the first completes.
Follow that case through the same components. Where is the error handled? What state remains? What does the user see? Can a late result overwrite a newer one?
This often reveals the design more clearly than the happy path. Error handling exposes assumptions about ownership, timing, and what the system considers recoverable.
Make a small, evidence-backed map
Write a short summary with source locations:
File selection
→ load or reuse the document
→ open an editor tab
→ update the active reading context
Still to verify:
cancellation during loading
changes to an already-open file
The map should distinguish established facts from open questions. Avoid filling a gap with a plausible story simply because the surrounding architecture looks familiar.
Tests help refine the map. Read what they assert, including edge cases and setup. A test name can suggest an intention that its assertions do not fully establish.
Let your next question choose the next file
A useful reading session ends with a clearer explanation and a smaller set of unknowns. You might now know how a document opens while still needing to understand cache invalidation. That is progress: the next question has a specific shape.
An AI reader can help locate code and propose a route through it. Ask it to show the evidence for each important step, then inspect the source yourself. Keep the final model in your own words.
Yenpo brings local navigation and that conversation into the same workspace. The reading guide walks through the mechanics; asking useful questions helps you keep the investigation focused.