Skip to content
Tanner Young
All posts

Notes on Reading Code You Did Not Write

2 min readUpdated August 2, 2026

Placeholder post. Sample content for verifying the layout — swap in your own. Note this one sets updatedDate, so the post header renders the “Updated” line.

Most advice about reading unfamiliar code tells you to start at the entry point and follow the calls. I have never found that to work. Entry points are usually the least interesting part of a system: argument parsing, config loading, a dependency graph being wired together. You can read all of it and learn nothing about what the software actually does.

Start with the data

Find the core types first. In most systems there are three to five structures that everything else exists to transform, and once you can name them, the functions stop looking arbitrary.

// The shape of the data usually tells you more than the call graph.
interface Order {
  id: OrderId;
  lines: LineItem[];
  status: 'draft' | 'placed' | 'fulfilled' | 'cancelled';
  placedAt?: Date;
}

That one type implies a state machine, an audit trail, and a set of invariants — placedAt presumably exists exactly when status is not draft. You have learned the domain before reading a single function.

Then read the tests

Tests are documentation that fails when it goes stale. They also tend to describe behavior at exactly the altitude you want when you are new: what goes in, what comes out, which edge cases someone cared enough to pin down.

Look for the test file with the most cases. That is where the hard part lives.

Then change something small

Understanding plateaus quickly if all you do is read. Pick a trivial change — rename something, tighten a type, fix a typo in an error message — and get it through the build. You will discover the parts of the system that documentation never mentions: how long the tests take, which lint rules are load-bearing, what breaks when you touch a “shared” module.

The sequence

  1. Core data types.
  2. The densest test file.
  3. One small change, end to end.
  4. Then the entry point, which now reads as assembly instructions.

Reversing steps one and four is the mistake I made for years.