Reading code is a skill and nobody teaches it
We spend years learning to write and approximately zero hours learning to read. Then we spend our careers reading.
Every programming course teaches you to write code. Not one of them teaches you to read it.
Then you get a job and spend, conservatively, eighty percent of your time reading: reading the existing system before you change it, reading a pull request, reading a library's source because the docs are wrong, reading a stack trace, reading a diff a machine produced.
The skill you were never taught is the one you use most. And it is a skill — it is learnable, it has technique, and people are dramatically better or worse at it in ways that have little to do with how well they write.
what good readers actually do#
I have watched a lot of people read unfamiliar code. The good ones have a method.
They find the entry points first. Not the top of the file. The place where control enters the system: main, the route handlers, the message consumers, the event listeners. Everything else is reachable from there and unreachable code is noise.
They read for shape before detail. A first pass that answers: how many layers? Where is the state? What talks to what? They will read a hundred files shallowly before reading one deeply, and they resist the urge to understand any single function completely on the first pass.
They follow the data, not the calls. Where does this value come from, where does it go, who mutates it. Call graphs tell you the structure; data flow tells you the behavior, and bugs live in behavior.
They run it. Reading static text is a bad way to understand a dynamic system. Set a breakpoint, add a print, run the test with a debugger attached. Five minutes of watching it execute beats an hour of reading.
They read the tests first, when the tests are good. Tests are the spec written in a language the machine checks. A well-tested module's test file is the best available documentation of what it is supposed to do.
They read the history. git log -S for the function name. When was this added, what was the commit message, what else changed with it. The rationale for a weird piece of code is frequently in a commit from 2019, and nobody looks.
They accept partial understanding. The bad habit is trying to understand everything before touching anything. You cannot. Understand enough to make the change safely, make it, and let the tests and the review catch what you missed.
the techniques worth practicing deliberately#
Read a library you depend on. Pick something in your stack, one you use daily and have never opened. Read its source for an hour. You will learn more about your language's idioms than from any tutorial, and you will find at least one thing that changes how you use it.
Explain it to someone. The fastest way to discover you did not understand something is to try to say it out loud. This is why rubber-duck debugging works and it works just as well for comprehension as for debugging.
Reconstruct the design decision. For any piece of code that looks strange, ask: what problem would make this the right answer? Usually there was one. Code that looks stupid is either a workaround for something you cannot see, or a fossil of a requirement that no longer exists. Both are worth knowing.
Diff two versions of something. Reading the evolution of a file teaches you what the author learned. It is a much richer signal than the current state.
why this matters more now#
Because reading is now a much larger fraction of the job.
If a machine writes a substantial share of the code that lands in your repository, then your value-add is on the reading side of the transaction. The person who can read a 400-line diff and spot the one place that breaks under concurrency is worth enormously more than the person who can produce 400 lines.
And it compounds badly in the other direction: someone who never developed reading skill, in an environment where they write less code than any previous generation, will develop neither.
the thing I would change about how we teach#
Give students a real codebase and a bug report before you give them a blank file.
Have them find it. Have them explain what the system does. Have them make a one-line fix and defend why it is correct.
That is the actual job. We spend four years preparing people for the part of it that machines now do well, and zero hours on the part that they do not.
— Dom, January 13, 2026