Skip to content
Trade offs in architecture

I've fallen for the same trap multiple times in my career, and I bet you have too. In the tech industry buzzwords like "new framework," "design pattern," or "clean code" get thrown around, but few engineers apply them while understanding the trade-offs. It's tempting — and I can relate. It's exciting to work with a new framework you've discovered. You go through the documentation, carefully reading the "Getting Started" section. You even spend your weekend trying the framework out, writing code, dealing with compilation issues, and debugging. Every hour you invest makes you fall more in love with the new framework. It doesn't help that there's a growing community around it, with everyone hyped about how revolutionary this technology is. Enchanted by the framework, you completely forget to dig into the real use case and understand the trade-offs.

This is the root of flawed thinking. You have this new framework, and suddenly it seems like you can solve every problem with it — or at least it appears that way. But I can tell you there's no one-size-fits-all approach in technology. Understanding the trade-offs helps you make informed decisions. It's like cramming a square object into a circular hole — you might be able to do it with the right approach (and the right size square), but that's not how it was meant to be used.

The Vue Reality Check

To illustrate this better, let me share one of my stories from the past. I was working on a pet project — a web application. When Vue came out, I wanted to give it a try since I had worked on Angular applications before. It was this new framework that "the cool kids" were using, and I had to try it out. I jumped in, checked the documentation, and started playing around with it. After a while, I was convinced of how amazing it was. Then I decided to actually build something substantial with it, not just leave it at small code snippets. Boy, did I hit reality fast. After the honeymoon phase, I quickly stumbled upon the first issues. There were only a handful of npm packages for Vue, and download numbers were in the low hundreds per day. You also had the problem that there was no official CLI, and modern dev tooling (today often Vite-based) didn't exist. Developers had to hand-roll Webpack/Gulp/Browserify setups around Vue, which seemed riskier than using Angular's CLI or create-react-app once those appeared.

The Android App That Never Was

But this wasn't a one-time occurrence where I forgot to think about use cases and trade-offs. If I rewind a bit further back in my career, I fell into the same trap before. When the first tablets came out, I was really eager to work on an Android app. Of course, I immediately pitched the idea of porting the company's desktop application to Android. I thought customers would be thrilled to know we were following trends and being revolutionary. Back then, iOS and Android apps were emerging, and it felt like this new shiny thing I needed to pursue. Luckily, we had a great product owner, and my idea was dismissed at the start. The product owner rejected the proposal because the work couldn't be justified — we might get additional revenue, but the investment would never pay off.

When KISS Becomes Complicated

But this phenomenon isn't exclusively tied to new languages or frameworks. The same can easily happen with "best practices," "patterns" and other "software principles." This brings me to another story. In my mid-thirties, I worked as a senior engineer at a company. I had a junior developer on my project, and in one pull request, he applied the KISS principle (Keep It Simple, Stupid). I went through the PR and noticed how he had over-generalized some functionality to apply the principle. I explained in the PR review that while KISS is useful, if it's misunderstood as "always choose the smallest/most generic bit of code," it can backfire and make a system harder to change and reason about. He had over-generalized one piece of code for multiple use cases just to avoid code duplication.

The realization

Through all these stories, I'm trying to make the point that everything has trade-offs and specific use cases. The more experience you gain, the better you become at recognizing these trade-offs and use cases. This shouldn't mean you shouldn't try new things, but rather that you should be realistic and ask yourself these simple questions:

  • What specific problem am I trying to solve? Define the actual problem first, not the solution you want to use.
  • What are the alternatives, and why is this approach better? Consider existing solutions and understand the comparative advantages.
  • What is the maturity and ecosystem support? Evaluate community size, documentation quality, and long-term viability.
  • Do I have the team expertise and time to implement this properly? Be honest about your team's capabilities and available resources.
  • What happens if this technology becomes obsolete or unsupported? Consider migration paths and exit strategies.
  • Am I choosing this because it's genuinely the best fit, or because it's exciting and new? Check your motivations and bias toward novelty.

These questions won't guarantee perfect decisions, but they will help you pause and think critically before diving headfirst into the next shiny thing. Remember, the goal isn't to avoid innovation — it's to innovate thoughtfully.

Published by...

Image of the author

Jernej Klancic

Visit author page