Skip to content

Books

A Philosophy of Software Design

Editorial pick

By John Ousterhout · Yaknyam Press · 2018

The book that taught a generation of senior engineers a new vocabulary for 'why does this code feel bad?'

Framework Under 200 pages(196p) Intermediate Published 2018

Editorial take

Most software engineering books are either too abstract (Knuth) or too tactical (refactoring catalogs). Ousterhout's slim volume hits a gap in between: a short, opinionated set of principles for managing complexity at the module-and-interface level, with rich examples drawn from teaching the corresponding Stanford class for years. The concept of "deep modules" vs. "shallow modules" alone is worth the cover price, and "comments are required documentation, not annotations" is a position you'll find yourself defending in code review again and again. Read it, then re-read it after you've shipped a major piece of infrastructure.

Last hand-checked 2026-05-18, Read the 2nd edition (2021) — the new chapters on AI/LLM code generation are worth the upgrade.

Read if you …

  • are a senior or staff engineer formalizing your taste in code review
  • feel that your codebase 'gets worse' as features get added but can't say why precisely
  • teach junior engineers and want shared vocabulary for design feedback

Skip if you …

  • you wanted a language-specific style guide — this is language-agnostic and principled
  • you're new to programming — the book assumes you've been bitten by complexity before

If you only read one chapter

Modules Should Be Deep

The cleanest distillation of the book's central thesis. Photograph the diagrams and put them in your team's wiki.

Key ideas

  • Complexity is the enemy. Most other principles serve managing complexity.
  • Deep modules: simple interface, powerful implementation. Shallow modules are net negative.
  • Comments should describe things that aren't obvious from the code — the why, not the what.
  • Define errors out of existence whenever possible.

About the book

John Ousterhout's distillation of his Stanford CS 190 course on software design. The book argues that the most important attribute of well-designed software is whether it minimizes complexity, and offers a set of design principles — deep modules, information hiding, careful comments, error handling — for getting there.

The writing is unfashionably opinionated. The book takes positions on commenting practice, on tactical-vs-strategic programming, and on when to refactor — positions that experienced engineers will find clarifying or annoying in equal measure, but rarely empty.

If A Philosophy of Software Design works for you, these likely will too.