Skip to content
AhmadKhidir

POST

The boring skill that compounds: reading code

Aug 20266 MIN READ

#career#code-reading#collaboration#debugging

We have an entire industry built around teaching people to write code. Bootcamps, tutorials, leetcode grinders, AI assistants that generate code on demand. Nobody teaches reading code. The assumption seems to be that reading is the easy direction, that it happens automatically, that anyone who can write can obviously read.

It does not happen automatically. Reading code is a distinct skill with its own techniques, and it is the one that actually determines how productive you are inside an existing codebase. A developer who reads well lands in an unfamiliar repository and knows what to look at in an hour. A developer who cannot spends a week changing one file and hoping. I have watched this play out more times than I can count, on both sides of the junior to senior boundary.

Why reading is harder than writing

When you write code, you are in control. You hold the whole model in your head, the function you are building, the data it touches, the edge cases you care about. The code is your memory made visible.

When you read someone else's code, you are reconstructing a model from an artifact. The original author's intent is gone, the history is buried in git, and the code has been shaped by years of feature requests, bug fixes, and deadlines. The structure reflects decisions you can only guess at. You are doing archaeology, not reading prose, and the artifacts do not come with context labels.

The failure mode is people reading code linearly, top to bottom, like a book, and trying to hold it all in their head. That is not how code works. Code is a graph, and you should traverse it like one, following the paths that matter and ignoring the rest until they matter.

Start with the entry point, not the file

When you open a repository you have never seen, do not open a random file and start reading. Find the entry point. For a web service that is usually the route definitions or the main handler. For a library it is the public API. Work outward from there, following the call graph, and resist the urge to read everything.

The discipline that separates good readers is the willingness to skip. You do not need to understand the logging middleware to understand how a payment is processed. You need to know it exists and that it wraps the handler, and that is enough. Read the spine of the system first, the routes, the data model, the request and response shapes. Fill in the details only when they matter to your task.

The four questions every codebase answers

I have found that almost everything worth knowing about an unfamiliar codebase reduces to four questions. What does the system do? What is the shape of the data? Where does the behavior live? How does it fail?

What does the system do is answered by the entry points and the domain language. What is the shape of the data is answered by the models, the schemas, the types. Where does the behavior live is the interesting one, because in a well organized codebase the answer is predictable, and in a messy one it is not. How does it fail is answered by the error handling, the logs, and the tests that document past incidents.

Tests are the gift you give your future reader, and they are the best documentation most codebases will ever have. A test shows you what the author believed the system should do, with real inputs and expected outputs. When I need to understand a function, I read its tests first. They are shorter than the implementation, they state the contract, and they show the edge cases that the author actually cared about.

Use the tools the way they were meant to be used

Reading code is faster when you stop reading files and start reading symbols. An editor with go to definition, find references, and call hierarchy turns code reading from a linear slog into a graph traversal. The developers who navigate quickly are not smarter. They are using the tooling to follow the graph instead of scrolling.

Git history is underrated reading material. The blame view, the log of a file, the commit that introduced a mysterious line, these answer the question that static code cannot: why. A strange check for a null value makes sense when you see the commit message about the production incident that added it. A duplicated function stops looking like incompetence when you see it was vendored from a library that was removed.

The discipline of reading history also changes how you read the present. Code that has been touched by many people over many years is legacy in the good sense: every line has survived something. Treat it with respect. Code written last week in a spike branch is scaffolding. Treat it with suspicion.

Reading is a team sport

The best way to get better at reading code is to watch someone else do it. Pair programming, or a focused walkthrough where a senior dev traces a request through the system and explains what they are looking at and why, is a masterclass in reading technique. The explicit narration is the thing you cannot get from a book: watch what they skip, what they follow, what they look up, what makes them stop and think.

Code review is reading practice with a purpose, and it is the reason the reviewers who read deeply are the ones whose comments are worth having. A reviewer who reads the diff and the surrounding system, traces the data flow, and checks the failure modes is doing the same archaeology, under the mild pressure of catching something before it ships.

The compounding effect

Reading is slow at first. When you are new to a codebase, everything is unfamiliar and every path is a new exploration. This is normal and it is not a sign of failure. What compounds is the map. Every codebase you learn is a map you keep, and the maps reinforce each other. The second codebase is faster than the first, because you recognize the patterns. The tenth codebase you can walk into and find the seams in an afternoon.

The developers who seem magically productive in unfamiliar systems are usually not fast writers. They are fast readers, with a mental library of patterns, a habit of starting from the entry point, and the discipline to skip what does not matter. That is a learnable skill, and it is the highest return one you will ever add to your toolkit.

Write the code. But read twice as much, and get better at the half of the job nobody trains you for.