Home

Read the source, not the documentation

For my first two years I treated open-source code as something other people wrote and I consumed. Documentation was for learning; source was for the maintainers. That was a mistake, and fixing it changed how fast I improved more than anything else I have done deliberately.

What the documentation cannot tell you

Documentation says what a function does. It rarely says:

  • What it costs. Is it O(n)? Does it allocate? Does it take a lock?
  • What it does in the edge case the author did not think to document.
  • Why the API is shaped that way, which is usually the most useful thing to know.
  • What it does when it fails, beyond “throws an error”.

All four are in the source, and the fourth is the one that has saved me the most time. “Throws an error” versus “returns nil after logging” versus “traps” are three completely different things to design around, and the documentation for the same function will describe all three as “handles invalid input”.

Starting small

The mistake is trying to read a codebase. Nobody reads a codebase. The unit that works is one function you already use.

Concretely:

  1. Pick something you called this week. Array.append. String.split. URLSession.data(for:).
  2. Command-click it in Xcode to see the declaration.
  3. Find the actual implementation — for Swift’s standard library, that is apple/swift under stdlib/public/core/.
  4. Read it, follow it down one level, and stop.

Twenty minutes. The first time I did this with Array.append I finally understood copy-on-write — isKnownUniquelyReferenced, the buffer, the reserve capacity growth — after a year of reading blog posts about it that all said the same paragraph.

What is worth reading

The Swift standard library. Surprisingly readable, well-commented, and it is the code you use most. Array, String, Optional, Sequence. The comments explain design decisions, not just behaviour.

Swift Evolution proposals. These are not source but they are the closest thing to a design rationale that exists. Every language feature has one, and it includes the alternatives that were rejected and why. Reading the async/await proposals taught me more about structured concurrency than any tutorial.

Any dependency you have debugged twice. If a library has confused you more than once, an hour in its source is cheaper than a third confusion.

Rust’s standard library, if you write Rust. It is heavily commented and the Iterator adapters in particular are worth reading — they are the clearest demonstration I know of how zero-cost abstractions actually work.

Tip

Read the tests before the implementation. A library’s test suite is executable documentation of every edge case the author thought of, and it is usually much shorter than the implementation. For “what does this do when the input is empty”, the test file answers faster than the source does.

Three things that make it easier

Use git log and git blame on the confusing part. A strange-looking line usually has a commit message explaining it, and often an issue number. The line is weird because of a bug you have not hit yet.

Follow one path, not the structure. Do not try to understand the module. Pick an entry point and follow one call chain down. Understanding one path through a system teaches you more than a map of its files.

Accept not understanding most of it. I read the parts of the standard library I need and skip the rest, including things that have defeated me twice. That is normal and it is not a failure — the goal is to answer one question, not to comprehend a codebase.

What it is not for

I am not arguing you should read source instead of documentation. Documentation is faster for “what are the parameters” and “is there a function that does X”, which is most of what you need most days.

The source is for the questions documentation cannot answer, and there is a specific moment where that shift pays off: when the documented behaviour and the observed behaviour disagree. At that point every additional minute reading the docs is wasted, because they describe the intent and you are looking at the implementation.

Recognising that moment quickly is most of the skill. The rest is being willing to open the file.