You shipped something and it works. But then a user hits a bug, or you need a feature that touches code you didn't write, and you open the file and realize you're reading it for the first time.
Reading code is a separate skill from writing it, and it's the one that gets skipped in this new AI doing the coding for you world. So how do you actually read code you didn't write?
Never read a file top to bottom
Reading a code file from the first line to the last feels like the obvious way to understand it, but usually it just leaves you trying to remember a pile of function names before you know which ones matter.
Start with one thing the app actually does. Pick a login, a form submission, or a page load and trace that one path all the way through. Find where the request comes in, what gets called next, what that code touches, and what eventually gets returned. Ignore anything that is not part of that path.
Do that a few times and the rest of the codebase starts to look familiar. Most projects reuse the same patterns. Once you understand how one endpoint is put together, the next twenty or thirty are usually variations of the same thing.
Read data, not logic
The faster route into an unfamiliar codebase runs through its data, not its functions.
Start with the schema. Tables, columns, and how they relate tell you what the application actually thinks exists in the world, and every function eventually reduces to moving that data around. A schema is also small, honest, and rarely lies about intent the way a function name can.
Then the types. In a TypeScript project the type definitions are a compressed map of every shape flowing through the system. Ten minutes there beats an hour in the handlers.
What to skip on the first pass: error handling, logging, styling, config, tests. All useful, none of it explains what the thing does. You can read a file and deliberately ignore two thirds of it.
Use the agent to explain, not to edit
The same tool that wrote the code is also one of the quickest ways to understand it. Most people skip that part and go straight to asking it to change things.
Ask it to walk you through a path instead. What happens after a user submits this form? Which files get involved, and in what order? Where does this feature live? What is this function doing here?
One especially useful question is what would break if you deleted something. The answer forces the agent to tell you what depends on it, which usually explains the function better than a line-by-line description.
Verify against the code rather than trusting the summary, since a confident explanation of code that doesn't exist reads exactly like a correct one. And ask about code that's already in front of you, so checking takes seconds.
The trap is obvious once named. Using the agent to understand builds your model of the system. Using it to skip understanding builds nothing, and it's the same conversation either way, which is why the line between the two is so easy to cross.
Change something small on purpose
Reading alone doesn't stick. Understanding arrives when you predict and then check.
Pick something tiny and reversible. Change a label, add a field to a response, make one function return something slightly different. Before you run it, say out loud what you expect to happen and what else you expect to break. Then run it.
When you're right, that part of the map is real. When you're wrong, you just found the thing you misunderstood, which is worth more than the ten files you read correctly. Wrong predictions are the whole point; they're where the map gets corrected.
You don't need to understand every line of what you shipped. You need to know where things live, what talks to what, and where the data goes, which is enough to fix a bug at 2am and enough to tell when a proposed change is about to touch something it shouldn't. Most people who build with agents never get there, and the ones who do got there by reading three paths and breaking one label.






