Frameworks and the Cost of Hidden Complexity

Introduction — The Contemporary Paradox
We live in a time of unprecedented abundance in software development.
We have more tools, more frameworks, more libraries, more compute power, and more developers than ever before. And yet, something feels off. Systems are harder to reason about. Debugging is slower. Simple problems require complex setups. And failures often manifest far away from their real causes.
This is the paradox: productivity appears higher, but understanding is lower.
This article is not an attack on frameworks, nor a nostalgic plea to return to the past. It is an attempt to describe a structural shift in how complexity is handled—and too often, hidden.
Before Frameworks: Constraints, but Clarity
Before modern frameworks became dominant, development environments were undeniably harsher. Memory was scarce. Tooling was limited. Automation was minimal. Many things had to be built by hand.
But one property was almost always present: the execution path was visible.
When something failed, you could usually trace the flow:
- a request entered here,
- this function was called,
- this file was parsed,
- this line caused the problem.
The code might not have been elegant, but it was legible in a very practical sense. Cause and effect were closely linked. The developer knew where to look, even if fixing the issue took time.
This did not make developers better by nature—but it forced a form of responsibility. You owned the whole stack you touched.
Abstraction or Occlusion?
Frameworks promised relief from repetitive work. And in many cases, they delivered.
Good abstraction reduces cognitive load. It removes irrelevant detail while preserving the ability to reason about the system.
But abstraction has a failure mode: it can stop reducing complexity and start hiding it.
Modern frameworks often introduce:
- implicit behavior,
- convention-based magic,
- lifecycle hooks triggered out of sight,
- configuration scattered across files and formats,
- execution paths that only exist at runtime.
At that point, the developer no longer reasons about what the program does, but about how the framework might react.
Complexity is not removed. It is displaced—outside the developer’s mental model.
Technical Debt as a Business Model
Technical debt is often described as an unfortunate side effect. Something accidental. Something to be repaid later.
In reality, it has become structural.
Framework-driven development optimizes for:
- speed of initial delivery,
- onboarding velocity,
- short-term feature throughput.
The cost is paid elsewhere:
- refactoring postponed indefinitely,
- layers added instead of simplified,
- upgrades that require rewrites,
- teams that rotate before understanding the system.
Debt is no longer an exception. It is expected, planned, and normalized.
When the framework evolves faster than the product, understanding becomes optional—until it suddenly becomes impossible to avoid.
The Forgotten UX: Developers
Much attention is paid to user experience. Rightfully so.
But developer experience has quietly degraded.
Consider what is now considered acceptable:
- having to clear caches to fix broken behavior,
- non-deterministic builds,
- errors that disappear when dependencies change order,
- tooling that must be restarted to regain consistency.
These are not minor inconveniences. They are symptoms of systems that developers no longer fully control.
When the primary interface to your software is unstable, productivity gains are an illusion.
What We Lost Along the Way
Without romanticizing the past, it is worth naming what has been lost:
- end-to-end understanding,
- direct responsibility for behavior,
- fast, local reasoning about failures,
- confidence that the system does what you think it does.
These qualities do not scale automatically. They require discipline, restraint, and sometimes saying no to convenience.
Conclusion — The Tool Is Not the Enemy
Frameworks are not the problem.
The problem begins when tools replace understanding rather than support it.
A tool that saves time today but prevents comprehension tomorrow will eventually cost more than it delivers. Not always immediately, not always visibly—but inevitably.
Progress in software is not measured by how quickly we can assemble systems, but by how well we can still reason about them once they exist.
Understanding is not optional. It is the real infrastructure.
Alexandre Vialle