Back to Writing

Reading code is a skill, and I'm still bad at it

Notes from spending a week diving into an unfamiliar codebase, and the habits that finally made it click.

We spend a lot more time reading code than writing it, and yet almost nobody teaches reading. I joined a new project last month and spent the first three days completely lost. Here’s what eventually worked.

Start at the entry points, not the README

READMEs describe the project the author wishes existed. The entry point , main.ts, app.tsx, the route definitions , describes the project that’s actually there. I now start every new codebase with:

# Find the real entry point
fd -e ts -e tsx 'main|index|app' src/

# See what the routes actually are
rg -n "router\.(get|post|put|delete)" --type ts

Trace one request all the way through

Pick the smallest endpoint or button click in the app. Follow it from the user’s tap to the database and back. Don’t try to understand everything , just one path. You’ll learn the project’s conventions for routing, validation, error handling, and data access in one sitting.

For me, that looked like:

tap "Save"
  → onSubmit handler in EditNoteScreen
  → notesRepository.update()
  → /api/notes/:id PUT
  → noteService.update()
  → noteRepository.save()
  → response back up
  → optimistic UI rollback on error

By the time I’d traced one request, I knew where validation lived, which layer owned errors, and how the team thought about state. Three days of confusion saved by two hours of focused tracing.

Take notes the codebase can’t

The codebase already documents the what. Your notes should capture the why and the weird , the stuff future-you will lose otherwise:

# Codebase notes

- `notesRepository` is NOT the real DB layer , it's a wrapper that
  also writes to the offline cache. Real persistence is in `db/notes.ts`.

- The auth middleware runs twice on /api/notes/:id. Once for the route,
  once inside noteService. Probably a bug, ask before "fixing" it.

- Tests use `setupServer()` not `beforeEach`. Don't import jest globals.

What I’m still bad at

Resisting the urge to refactor while reading. Every codebase has quirks. Most of them are load-bearing in ways that aren’t visible yet. The discipline is to read first, judge later , something I have to remind myself every single time.