Systems Thinking

Published: (February 6, 2026 at 12:24 AM EST)
4 min read

Source: Hacker News

Two Schools of Thought in Software Development

  1. Evolutionary (incremental) development – start small, add features over time, and let the system grow organically.
  2. Big‑up‑front (engineering) design – write a comprehensive specification that captures all complexity before any code is written.

In a nutshell, it’s the difference between how an entrepreneur builds a startup versus how we construct modern skyscrapers: Evolution vs. Engineering.

A Real‑World Example

I once worked at a large enterprise that owned > 3,000 active systems spanning dozens of lines of business and every internal department.

  • The landscape had evolved over ~50 years.
  • It comprised many technology stacks, countless vendors, and a patchwork of legacy and modern applications.
  • Viewed as a single “thing,” it resembled a shaky house of cards.

What If There Were Fewer, Bigger Systems?

  • Data, security, operations, quality, and access inconsistencies would shrink dramatically.
  • The mix of up‑to‑date, ancient, well‑functioning, and barely‑functional systems would be replaced by a more uniform platform.
  • Overall complexity could drop to ≈ 10 % of its current level, not just half.

Resulting benefits

  • Better performance and reliability
  • Greater resilience to change
  • Lower cost and fewer staff required
  • Elimination of many “ugly” problems that exist today

The Core Issue: Dependencies

AspectEvolutionary ApproachBig‑Up‑Front Design
AssumptionDependencies can be ignored initially and resolved later.All dependencies must be identified up front and drive the design.
ProsFaster start, immediate progress, less coordination needed.Architecture is coherent from day 1, fewer hidden surprises later.
ConsHidden dependencies become expensive to fix later; “hacks” accumulate, leading to spiralling complexity.Requires heavy coordination, many meetings, and upfront friction among teams.

If you have thousands of independent blobs, you could simply “bang out” each one. In reality, very few components are truly independent, which makes the evolutionary route risky as the system scales.

Why Big‑Up‑Front Designs Stall

  1. Lack of Knowledge – Foundations (tech stacks, frameworks, libraries) evolve rapidly, leaving few universally accepted best practices.
  2. Short Career Paths – Most application programmers have ≤ 5 years of deep experience; veteran “20‑year‑plus” engineers are rare.
  3. Complexity Intimidation – Novice developers often feel unprepared to tackle massive, inter‑dependent designs.

Personal Preference & Reality Check

Evolutionary Projects

Pros

  • More fun, fewer meetings, immediate hands‑on work.
  • Less upfront coordination; you can “just get into the work.”

Cons

  • As the codebase grows, the risk of derailment rises.
  • Late‑stage panic when the system doesn’t behave as intended.
  • Long‑term dissatisfaction when you realize you’ve added to the problem rather than solved it.

Big‑Up‑Front Designs

Pros

  • Slower start but smoother overall development flow.
  • Allows deliberate attention to detail, reuse, and architectural consistency.
  • Reduces stress in the long run; you have time to do things right.

Cons

  • Perceived friction: many meetings, heavy coordination, slower early progress.

Note: The fear that a large upfront project will produce the wrong product is often overstated. In mature business domains with well‑understood requirements, a solid specification can actually reduce risk.

Bottom Line

  • Evolutionary development works well for small, fast‑moving initiatives where the problem space is fluid.
  • Big‑up‑front engineering shines when the domain is stable, the cost of hidden dependencies is high, and the organization can afford the upfront coordination.

Choosing the right approach depends on the nature of the problem, the maturity of the team, and the tolerance for long‑term technical debt.

Refactoring the Original Work and Addressing Its Deficiencies

There should be a balanced path somewhere in the middle, but I haven’t found a formal version of it after all these decades.

We could start with the dependencies, then explain why they can be temporarily ignored. You can evolve the next release while still keeping a vague, long‑term design in mind. As new, unexpected dependencies appear, you can refactor the design accordingly. Change your mind repeatedly, trying to get the evolving work to converge on a solid grand design.

  • Start fast, slow down, speed up again, and repeat.
  • The goal is a single, comprehensive system that eventually “rules them all,” even if it takes a while to get there.

Iteration Size Matters

The size of each iteration is crucial:

  • Tiny iterations often indicate blind stumbling forward.
  • Longer iterations (when you’re not stumbling blindly) are more effective.

Iterations don’t have to be uniform, but you should stop and take stock after each one.

  • The faster people code, the more cleanup is required.
  • Delaying cleanup makes the problem grow exponentially.
  • Running forward unchecked turns the working environment into a swamp that eventually grinds to a halt.

This principle applies to building anything—from software systems to cooking in a restaurant. Speed is always a trade‑off.

Balancing Evolution and Engineering

  • Evolution helps avoid getting bogged down in engineering, but engineering ensures the product does what it’s supposed to do.
  • Engineering is slow; spinning out of control is far slower.
  • Evolution is dynamic but chaotic; you must constantly recognize when you’ve taken a bad path and backtrack, which can be hard to admit.

For most systems:

  1. Engineered parts – components that must be carefully designed and validated.
  2. Evolved parts – sections that can be allowed to change organically.

The more random the evolutionary path, the more you’ll need to discard and redo. Wobbling is always expensive. Nature copes by having millions of species, but we typically have only one development project—so the stakes are higher and the process less convenient.

Back to Blog

Related posts

Read more »

Do we still need DTO ?

!Cover image for Do we still need DTO ?https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads...