Skip to main content

On Software Complexity

An exploration of why modern software is so complicated

On Software Complexity

Modern software is extraordinarily complex. A typical smartphone app might depend on hundreds of libraries, each with their own dependencies, running on an operating system with tens of millions of lines of code, communicating over protocols that took decades to develop.

How did we get here? And is this complexity necessary, or have we painted ourselves into a corner?

The Growth of Complexity

Software complexity has grown roughly exponentially since the 1960s. The first programs were measured in hundreds of instructions; today’s large systems comprise billions of lines of code.

Several forces drive this growth:

  1. Moore’s Law enabled it: Faster hardware means we can afford more abstraction layers
  2. User expectations increased: We expect software to do more, look better, work everywhere
  3. Backward compatibility: Old code must keep working, so new code works around it
  4. Security requirements: Each vulnerability discovered adds defensive complexity

The Abstraction Tax

Every abstraction layer helps us think about problems at a higher level. But abstractions leak. When something goes wrong, you need to understand the layer below, and the layer below that.

A modern web developer might need to understand:

  • HTML, CSS, JavaScript
  • React or Vue or Angular
  • Node.js and npm
  • HTTP, REST, GraphQL
  • SQL and ORMs
  • Docker and Kubernetes
  • Cloud services (AWS, GCP, Azure)

That’s a lot of concepts just to show text on a screen.

Is There Another Way?

Some efforts push back against complexity:

  • Plain text: Markdown, plain text files, simple formats
  • Single-file programs: Tools that fit in one file you can read
  • Local-first software: Apps that work offline without cloud dependencies
  • Simplicity movements: Suckless, 100 Rabbits

Perhaps the future isn’t more complexity, but selective simplicity—choosing carefully where complexity adds value, and ruthlessly eliminating it elsewhere.

Conclusion

Complexity isn’t inherently bad. The question is whether it’s necessary complexity or accidental complexity. We’ve accumulated a lot of the latter, and cleaning it up is one of the great challenges in software engineering.


See also: The Future of Programming, Digital Gardens