No Silver Bullet is probably one of the most well-known essays on Software Engineering. It's a section from Fredrick Books' 1995 book The Mythical Man-Month which is itself a bestseller in the field. Despite being 25 years old, the essay is very relevant today.

Brooks wants us to dismiss the idea of a 'Silver Bullet' that could improve software development productivity, reliability, or simplicity by an order of a magnitude or more. No single technological or managerial innovation can get us there.

To understand why, we need to understand where complexity in software comes from. Brooks breaks down the complexity into two kinds – essential complexity and accidental complexity.

Essential complexity arises from representing the requirements the software needs to fulfil conceptually. It can't be easily abstracted away. For example: if you build a online payments system, you will need ridiculous amounts of business logic to handle fraudulent transactions, currency exchange rates, the variety of payment processors (Visa, MasterCard, Apple Pay, etc.), and many other things.

Accidental complexity arises due to the difficulty of representing the requirements in a language the computer can understand.

There is no silver bullet to solve software complexity because most complexity is essential. We have made big strides in removing accidental complexity from software development. For example the following innovations have helped developers reduce accidental complexity:

  • High-level languages
  • Better development environments and debugging tools
  • Programming paradigms: object-oriented programming, functional programming, etc.

But essential complexity remains, and there is no trivial way to get rid of it. It is now the dominant form of complexity in software development:

I believe the hard part of building software to be the specification, design, and testing of this conceptual construct, not the labor of representing it and testing the fidelity of the representation. We still make syntax errors, to be sure; but they are fuzz compared to the conceptual errors in most systems.

Brooks proposes a few ways to manage essential complexity:

  • Buy vs Build. E.g. don't build your own payments system when there are companies you can buy it from.
  • Requirements refinement and rapid prototyping. This is probably more popular today (Agile development, Lean startup) than in 1995.
  • Incremental development - growing software instead of building. Complicated things are best grown incrementally than built from scratch. I wrote about this previously.
  • Hire and grow great software designers. Great designers can minimize essential complexity by understanding requirements better and simplifying specifications.