Software design

26 sources of advice on structuring and debugging software.

These sources give advice on how to structure and debug software. Most are essays drawn from experience. This page lists 26 sources, oldest first where dated.

No Silver Bullet: Essence and Accidents of Software Engineering

Frederick P. Brooks, Jr., University of North Carolina at Chapel Hill. September 1986. Technical report version of a landmark essay.

Frederick Brooks divides software difficulty into essential and accidental parts. The report reviews the proposed fixes of the time and judges each too small. It ends with promising attacks on the essence: buying, prototyping, growing software and cultivating designers. The evidence is reasoned argument and the author's experience.

The Inner-Platform Effect

Alex Papadimoulis, founder of The Daily WTF. 21 April 2006. Short blog article naming an antipattern, with one code example.

This is a brief article from The Daily WTF. It defines an antipattern and shows it with code from one reader's story. It offers a name and a single example, with no wider survey.

The Devil’s In The Details

allspaw, on the Kitchen Soap blog. 30 March 2012. Short blog post introducing a research chapter, with reader comments.

This is a brief Kitchen Soap post that quotes a chapter on joint activity. It adds a few paragraphs of framing about engineering teams. The post mostly points to the chapter.

Learnable Programming

Bret Victor. September 2012. Long design essay with interactive demonstrations.

Bret Victor responds to a Khan Academy live-coding environment that cited the author's work. The essay lists five principles for environments and four for languages. Its evidence is mock-up demonstrations, thought experiments and past systems such as Logo and Smalltalk.

The Wrong Abstraction

Sandi Metz. 20 January 2016. Personal blog essay, republished from a newsletter.

Sandi Metz describes how a shared abstraction fills with parameters and conditionals. Soon nobody can follow it. The post offers a way back. Inline the code into each caller and trim it. Its evidence is a stylized sequence plus the author's own observations.

On the criteria to be used in decomposing systems into modules

Adrian Colyer, The Morning Paper. 5 September 2016. Blog summary of a 1971 research paper.

Adrian Colyer revisits a classic paper and reads it through modern microservices. The post retells Parnas's KWIC index example with two competing decompositions. Its evidence is that worked example and Parnas's own judgement.

Yes silver bullet

Mark Seemann. 1 July 2019. Personal blog post, argued from experience.

Mark Seemann rereads Fred Brooks's No Silver Bullet and disputes one assumption. The evidence is the author's own career anecdotes, which the post calls anecdotal. It ends with a conjecture about statically typed functional programming.

Software Architecture Guide

Martin Fowler (Thoughtworks). 1 Aug 2019. Curated guide page, with short essays and links to articles.

This is a hub page, not a single argument. Fowler states a short view of architecture. Then the page lists linked articles on application, enterprise and other topics. Several linked pieces are by other authors. The evidence is Fowler's experience and reported developer opinion.

Software is about people, not code

Dan, publishing as mooreds on Letters To A New Developer. 27 January 2020. Short advice letter on a personal blog.

The letter is a few paragraphs long and offers advice, not data. The author describes a shift from focusing on code to focusing on people. The source is short and makes three plain points.

Post introducing the essay Distilled Capability

Posted by dorian (doriantaylor.com), with replies from two commenters. 1 November 2024. Short social post linking to an essay.

This is a very short post with a link card and two replies. It says the essay was written to give a conceptual basis for the author's software. The post itself makes no argument.

How I ship projects at big tech companies

Sean Goedecke. 9 November 2024. Personal blog post of advice from experience.

Sean Goedecke defines shipping as a social outcome: leaders accept that the project is done. The post then lists habits for the project lead. These cover communication, early deploys and fallback plans. Its evidence is the author's own career experience.

Best Simple System for Now

Dan North, Dan North & Associates Limited. 3 February 2025. Personal blog essay, with two worked examples.

Dan North names a middle path between quick hacks and perfectionism. The essay answers three objections and gives two Java examples. Its evidence is the author's experience, anecdotes and cited writers, not measurement.

Developer philosophy

qntm. 2025-02-03. Personal blog post, a list of opinions, with reader comments.

The post is a loose list of rules, written after a talk for juniors. Each rule is a short argument from experience. It has no data. A comment thread of 14 replies adds some pushback and extra rules.

Ask HN: What are the best engineering blogs with real-world depth?

Posted by nishilpatel, with replies from many commenters. 23 December 2025. Hacker News Ask thread, with many link recommendations.

The poster asks for blogs that show real implementation detail and trade-offs. Replies mostly list company and personal blogs, plus aggregators, books and RSS feeds. A long side thread debates whether an LLM wrote the question, and what engineering means. The thread had 474 points.

High-Level Is the Goal

Posted by tobr, with replies from many commenters. 15 January 2026. Hacker News discussion thread of an essay.

The 276-point thread discusses an essay commenters call a push for better tooling. Commenters mostly argue about web frameworks, UI toolkits and why software feels slow. The essay's author replies in several places. The thread offers opinion and anecdote, with some code-level claims.

The third hard problem

Roman Kashitsyn (mmap(blog)). 2026-02-28 (a second date, 2026-06-04, is also shown). Personal blog essay, with examples from several fields.

The essay coins the term tree mapping. It means squeezing a graph of ideas into a hierarchy. It gives examples from file systems, writing, city design and biology. The evidence is a set of illustrative cases and quotations. It offers no measurements.

The Two Abstractions of System Design: Hide or Reduce

Murat Demirbas (principal research scientist at MongoDB Research). 8 May 2026. Personal blog post, argument with examples.

Murat Demirbas separates modularity abstraction, which hides internals, from modeling abstraction. Modeling abstraction reduces a system to what matters. The evidence is a list of well-known distributed systems designs. The post is a conceptual argument without data.

Learning Software Architecture

matklad. May 12, 2026. Personal blog post, a reply to an emailed question.

The post is a reply to a researcher who asked how to learn design. The author answers from experience leading the rust-analyzer project. It stresses incentives and team structure over technique, and ends with a reading list. The evidence is the author's own career anecdotes.

Cognitive load is what matters

Artem Zakirullin. June 2026 (last update of a living document). Living GitHub README essay, with code examples and anecdotes.

Artem Zakirullin treats cognitive load as a human limit and applies it to design habits. Sections cover conditionals, inheritance, small modules, microservices, layers and domain-driven design. Evidence is code snippets, personal anecdotes and quoted endorsements.

Interview With Mitchell Hashimoto

Alex Alejandre, interviewing Mitchell Hashimoto. July 2026. Written question-and-answer interview.

Alex Alejandre interviews Mitchell Hashimoto, who built HashiCorp tools and now builds Ghostty and Vouch. Hashimoto gives first-person views on terminal design, maintainer obligations, AI use and learning C. The evidence is personal experience, and Hashimoto leads the projects discussed.

Towards a Theory of Bugs: The Ruliology of the Unexpected

Stephen Wolfram. 21 July 2026. Long essay with computational experiments.

Stephen Wolfram uses tiny Turing machines and cellular automata to show bugs that appear late. The essay ties bugs to computational irreducibility. It also discusses proofs, testing and AI-written code. The evidence is enumerated toy systems plus a few number theory cases.

Systems and Delays

Martin Janiczek. 24 July 2026. Personal blog post, with simulated examples.

The post retells one chapter of Thinking in Systems using a car dealership stock model. It reports simulation runs with three settings of a response delay. The author found the result counterintuitive: shortening a delay made oscillations worse. Evidence is a toy simulation the author wrote.

simple is not small

jyn. 27 August 2026. Personal blog essay, with code comparisons.

jyn starts from a talk about a coverage bug and asks about simplicity. The essay compares a Unix word-count pipeline with Clojure, then Rust with Clojure. Evidence is code samples and argument.

The Slow Formation of Durable Software

Dan Cohen (Humane Ingenuity newsletter). October 6, 2026. Personal newsletter essay, a first-person history.

Dan Cohen recounts Zotero's pre-history from early web tools through the 2006 release. The post uses dated emails, a grant abstract and screenshots. It draws a lesson about slow collaborative thinking versus instant AI coding. The account is from one participant's view.

Carl's Required Reading

Carl Kolon. Undated. Annotated reading list of articles and books.

Carl Kolon keeps a topic-grouped reading list with a short note per entry. Four favourites carry a star. The notes state opinions openly, such as dislike of ORMs.

The 7 Most Influential Papers in Computer Science History

Not stated. Undated. Personal blog listicle with short summaries and links.

A short list post on the Terrible Software blog. Each of seven papers gets a summary, a note on why it matters, and links. Five more papers appear as honorable mentions. The evidence is the author's taste, stated as such.

Glossary

Abstract data type (ADT)
A type defined by its operations while its internal representation stays hidden.
Abstraction
A named piece of code, such as a method or class, that replaces repeated logic.
Accidental complexity
Difficulty added by tools and methods, not by the problem.
Ada
A programming language of the 1980s designed for large, structured systems.
Aggregator
A site that gathers links from many other sites.
Antipattern
A common solution to a problem that tends to cause worse problems.
Basic Compact
A mostly unspoken agreement to take part in joint activity and coordinate.
Cache invalidation
Deciding when stored copies of data are out of date and must be refreshed.
Caller
The code that uses a shared method or class.
Catch_unwind
A Rust feature that catches a crash inside a section of code.
Cellular automaton
A grid of cells that update by a fixed local rule.
Circular shift
Moving the first word of a line to the end.
Cladistics
A biological method that groups organisms by shared ancestry.
Clojure
A programming language from the Lisp family.
Codebase
The full set of source code for a project.
Coding agent
An AI tool that writes and edits code.
Cognitive load
How much a person must hold in mind to do a task.
Cognitive systems engineering
A field that studies how people and machines think and work together.
Computational irreducibility
The idea that some processes can only be predicted by running them step by step.
Conditional
A branch in code that behaves differently depending on a value.
Conway's law
The idea that software structure ends up mirroring the structure of the organization building it.
Cost of delay
Value lost for each period a solution is not yet with customers.
Coupling
When parts of a program depend on each other so they cannot change separately.
Cruft
Messy or outdated code that makes software harder to understand.
CUPID
North's five traits of joyful code: composable, Unix-like, predictable, idiomatic, domain-based.
Customizable
Able to be changed by users without editing the program.
Dear Imgui
A C++ library that draws interface elements each frame.
Decomposition
Breaking a problem into smaller parts that can be understood separately.
Deep module
A module with a simple interface that hides much functionality.
Distributed monolith
Many services that must still change together.
DRI
Directly responsible individual, the single person accountable for a project.
DRY
A rule not to repeat the same code or knowledge.
Enterprise architecture
Coordinating the design of software across a whole large organization.
Essence and accident
Essence is difficulty inherent in the problem; accident is difficulty from the tools used.
Essential complexity
Difficulty that comes from the problem itself and cannot be removed.
Expert system
A program that uses a rule base and inference engine to give advice.
Feature flag
A switch that turns a feature on or off without redeploying code.
Feedback loop
A cycle in which a system's output changes the input that drives it.
Fork
A personal copy of a project's code that can be changed independently.
Gall's law
A rule of thumb that working complex systems grow from working simple ones.
Ground-up rewrite
Throwing away a codebase and building its replacement from scratch.
Handmade community
A group of programmers who favor writing software from low-level parts.
HATEOAS
A web design style where server responses carry the available next actions.
Hidden state
Settings, such as a current fill color, that change behavior without being visible.
HyperCard
An older Apple tool for building programs from cards and objects.
Information hiding
Designing each module to conceal one design decision from the others.
Information theory
The mathematical study of measuring, compressing and sending information.
Inlining
Copying a function's body into the places that call it and removing the function.
Interleaving
One possible ordering of steps from concurrent activities.
Internal quality
How clean and understandable the code is, as opposed to what users see.
Invariant
A property that must hold at every step of a system's run.
Joint activity
Work that two or more parties carry out together.
JQuery
An older JavaScript library that smoothed over differences between browsers.
KWIC index
A listing of every circular shift of each input line, in alphabetical order.
Linearizability
A consistency rule making concurrent operations appear to happen one at a time.
Live coding
An editor where the program's output updates as the code is typed.
LLM
A large language model, the kind of system behind chatbots.
Loan-origination system
Software that handles applications for loans.
Logo turtle
An on-screen character that a learner steers to draw shapes.
Memcached
A system that stores data in memory to speed up reads.
Microservices
A system built as many small, separately deployed services.
Monte Carlo simulator
A program that runs a model many times, often with random inputs.
NP-complete
Describes problems among the hardest in a class whose answers are easy to check.
OPML
A file format used to share a list of feeds.
Optimistic merging
Accepting contributions quickly and fixing problems afterward.
Order of magnitude
A factor of ten.
ORM
A library that maps database rows to objects in a program.
Oscillation
Repeated swings up and down instead of settling.
PageRank
Google's early method of ranking pages by the links that point to them.
Platform
The underlying system, such as a database or language, that software is built on.
Principle of Computational Equivalence
Wolfram's claim that most non-trivial systems are equally sophisticated computationally.
Processing
A language and library for drawing and animation, used in teaching.
Program verification
Proving mathematically that a program meets its specification.
PTY
A pseudo-terminal, the channel carrying bytes between a terminal and a program.
Pure function
A function that only computes a result and has no side effects.
Rapid prototyping
Building a quick working version to learn what the client really needs.
RAROC
Risk-adjusted return on capital, which weighs profit against money at risk.
Ratchet
A check that allows existing problems but blocks any new ones.
Redux
A library for keeping an app's state in one store.
Regression
A bug in behaviour that used to work.
Relational model
A way to store data in tables that can be queried with logic.
REPL
A tool that runs typed code and shows the result at once.
RSS
A feed format that lets readers follow new posts from a site.
Ruliology
Wolfram's name for studying what simple rules do when run.
Rust-analyzer
A tool that helps editors understand Rust code, written as a compiler front end.
Scribe
A FileMaker program for notes and citations, built at the center.
Semilattice
A structure where groups can overlap, unlike a tree where each item has one parent.
Shallow module
A module whose interface is complex compared with what it does.
Sharp end and blunt end
Practitioners who do the work, and the managers who shape its conditions.
Silver bullet
In folklore, a single cure for a monster; here, one fix for software problems.
Staging environment
A copy of production used to test changes before release.
Stock and flow
A stock is an amount held, such as parked cars. A flow changes it.
Struct
A fixed group of named fields in a program.
Sum type
A type whose values are one of several named cases.
Sunk cost fallacy
Keeping something because of effort already spent on it, not because it is still useful.
Taxonomy
A system for classifying things into groups.
Technical debt
Shortcuts in code that make later changes slower and harder.
Terminal emulator
A program that shows a text window where command-line programs run.
TLA+
A language for writing precise models of systems so their behavior can be checked.
TUI
A text-based user interface drawn with characters in a terminal.
Turing Machine
A simple theoretical computer made of a tape and a few states.
Unix pipeline
A chain of command-line programs, each feeding its output to the next.
Web Scrapbook
An early web app from the center for saving items from web pages.
Working memory
The small store of facts a person can hold in mind at once.
XUL
XML User Interface Language, which Firefox used to build and extend its interface.
YAGNI
A rule not to build features until they are needed.
Zig
A systems programming language known for fast compile times and frequent changes.
Zotero
A free tool for collecting, organizing, annotating and citing research.