
In recent years, applications have emerged that have become prisoners of their framework. In these applications, for example, critical bug fixes or security updates are no longer possible with reasonable effort because the framework has taken over and determines how the application is maintained and updated. And this becomes expensive.
Oh boy! How did we end up here?
Power
Power belongs to the coder and the application. Or at least that’s how it should be.
However, a coder can delegate power to frameworks, for example, and outsource many things to be handled by libraries. And this is often worth doing. Let’s delegate. Frameworks and libraries are very helpful for many problems. Whether it’s an ORM, dependency injection, or a web framework.
But can power be delegated too much?
Company Framework man
This is how it often happens. Too much power is delegated.
We’re doing it with Spring!1!
I see. Company Framework men.
In these cases, the entire application is usually written starting from the build file on the framework’s terms. And at the very least, the application’s main method has been outsourced to the framework.
Applications are literally bolted to the framework. Welded together intimately and tightly across the board. Every framework feature that can possibly be utilized is in use. The main method, tests, dependency injection, persistence, web interfaces, etc. And the codebase practically glows with the framework and its power.
And why not? If a framework is being used, then of course you should squeeze everything out of it, right? And one of the biggest promises of frameworks is to boost developer productivity. You just focus on the essentials and the framework handles the rest!
Sounds great! Or does it?
Control
Frameworks are details
– Uncle Bob
In order for the application and the coder to be in full control, no framework can manage the main method. And this is important.
But what’s the harm in letting the framework control things?
Dependency
The problem is the dependencies of the features offered by frameworks and the way frameworks are utilized. The more dependencies, the more features utilized, and the more places the framework is used, the tighter you are also bound to it.
Injection
Dependency Injection. This was perhaps the biggest selling point that allowed Spring, for example, to break through. Of course, many other things were involved, but dependency injection played the biggest part.
Attentive readers may realize at this point that dependency injection is just one manifestation of inversion of control. And if control is inverted starting from the main method, then what..?
Candy
Frameworks often have their own candies to offer. And this is the worst kind of doping. Whether it’s about data storage or other integrations. In most major frameworks, several “candy” interfaces are available for many libraries. A good example could be the Repository pattern, which often uses Hibernate under the hood.
But as with everything, it’s good to remember moderation.
One carefully considered treat isn’t necessarily very dangerous yet, but several can cause problems. Especially if it turns into overindulgence.
Too much candy
And this is where problems usually start to materialize and the hostage drama can begin.
The problem is practically related to the third-party libraries used by the framework, which can no longer be updated because the framework’s candy layer breaks due to these API changes.
Caricaturally, the story goes something like this:
Updating library X would require version 5 of the framework, but that in turn is incompatible with framework version 3, which is used with component Y, which is then incompatible with framework version 5.
Yes, now you can feel free to scream, throw the TV off the balcony, or otherwise just let off some steam. Most of us have encountered this in one form or another during our careers.
Poorly coded software that is tightly bound to frameworks can cause severe headaches when versions need to be bumped. Especially if there is a lot of code.
Effectively, this is about the jar hell / dll hell phenomenon.
Detox
Should the use of frameworks then be abandoned? Not necessarily. Frameworks are useful and help solve many problems easily. But they should only be utilized when the benefits obtained from them are greater than the disadvantages they cause.
It’s primarily about how frameworks are used.
The use of frameworks and other dependencies should be:
- Minimized.
- Only take what is needed and those that genuinely bring value.
- Ensure that the benefits are greater than the disadvantages.
- Picked individually with consideration and only at the last moment when the need materializes.
- Avoid using the "candy" interfaces provided by frameworks.
- Chosen conservatively, using stable, de facto solutions instead of the latest trend crazes.
- Restricted to certain modules or classes.
- Ensure that the domain remains clean and detached from the framework.
Performing a risk analysis can also be extremely valuable, especially if a framework and several of its candy layers are in use. This is important because applications are often running in production for a long time after they have been written. The world changes, but do the applications keep up and at what cost?
Architecturally, a good starting point is to use a domain-centric architecture such as Hexagonal Architecture. Domain Driven Design also guides towards solutions that are not framework-centric.
And it goes without saying that the application’s main method should be kept strictly in your own hands.
Summary
Many frameworks offer the possibility to outsource almost all the functions needed by the application to happen through the framework. You shouldn’t fall into this trap, but instead keep the reins strictly in your own hands and be aware of the burden caused by every dependency.
In a well-built modular application architecture, different parts of the application are easily replaceable. Frameworks and other dependencies should be taken into account when looking at the application’s modularity.
One of the biggest disadvantages of frameworks is that they easily lock in a large number of dependencies. In this case, updating an individual dependency may no longer be possible; instead, the entire framework must be updated at once. For this reason, minimizing and encapsulating the number of frameworks and other dependencies is important so that the potential blast radius remains as small as possible.
Domain-centric architectures and Domain Driven Design provide good starting points for keeping the risks caused by frameworks a bit more easily manageable.
But ultimately, the responsibility lies with us developers. We must also understand the risks associated with using frameworks.
If you are more interested in the topic, Uncle Bob’s book Clean Architecture has many good points on how to keep applications in your own hands.
And we at Bytecraft are also happy to help you or your partners find cost-effective solutions that stand the test of time. Whether it’s just a smaller sparring session, training, or an entire project. Feel free to contact us!




