Complex solution to a simple problem

A few years ago, I built a personal website using Nuxt 2. I chose it because I love the elegance of Vue. It worked fine. Until I decided it was time to remove the telegram link. So I updated the content, continued to build step, and ... got an unhandled error. Exit 1 – right, alright.

Cadini di Misurina

My first reaction was to update dependencies. But the longer I tried, the more errors I got. On top of that, I didn’t remember which node.js version I used initially. After hours of trying, I concluded it was wise to stop. Let’s clarify what happened and why.

Ground truth

The pace of change in frontend tooling is WILD. I didn’t realize my website could suddenly turn unmaintainable in just 4 years. In a sense, it was broken since the beginning.

Tools age naturally – as we do. I’m aware of that. Mine didn’t smoke, mine hasn’t drank, but it burned like a shooting star. So why did making a tiny change break the whole thing?

Because it was complex and fragile.

What happened?

Netlify relies on build image OS settings. When I created the website, Ubuntu 16.04 Xenial was the default one. Two years later, it was discontinued. So, I updated site settings to Ubuntu 20.x. But I forgot to add a new commit to test the build.

Misty forest in the Dolomites

And now my node dependencies have failed. I realized my runtime was updated from version 16.x to 18.x. Netlify changes played their part. And I played the role by not being strict about the runtime.

I could have dockerized my nuxt tiki-taka. In theory, using a container image makes sense. Does it pay off to add more moving parts to a static website? No, because Netlify can’t consume it.

Questions continued to pop up. What if I was using Golang or Rust instead? I knew I was doing something wrong.

From X to Y

Decent car engines can do a million kilometers. Jets fly for 40 years. If my work is fresh and nearly dead, it indicates the obvious. I have the software, but its engineering part seems to be missing.

People often ask: why invest in upgrading from x to y? Right on point! It must be balanced. I picked a technology that locked me in the vicious upgrade cycle.

Upgrades are expensive.

Balancing act

Engineers have a natural tendency to complicate things. Suggest a solution to a real-world problem. A new battery cell for an electric plane. I bet your group will eventually come up with another Frankenstein design. Otherwise, you are a genius!

Nuxt is an excellent open-source project. And it became so much better over time. Yet, I must admit that Nuxt 2 was more suited for R&D projects.

JavaScript frameworks in the wild

As with any intricate system - it’s a balancing act. Between non-engineering and over-engineering. When conditions change fast - complexity grows, and there is little time to fit everything together.

Talking about over-engineering, I think of Webpack and its plugins for plugins. A typical use case in the frontend community was to use it for replacing parts of static html.

The Italian in Webpackia

– Ma perché???
– We need to add unique links to assets in single-page apps.
– What about generating dynamic html on the server?
– Too easy for my Kompukter.

This website is using Next.js, which in turn depends on Webpack. Some tech choices are hard to undo.

Bicycle analogy

Next time you go for a walk – take a closer look at cyclists and their bicycles. Understand the quality of service just by looking at the chain. Steel chain seems like a cheap and plain solution, right?

Nope. Rain, sand, and oxygen make it a complex system hard to operate. To protect sprockets and chains, we use a clever hack - grease. It’s dirty, sticky, and sometimes toxic but essential for the whole mechanism.

Alee Denham made an outstanding video comparing belts and chains.

Steel chainCarbon belt drive
Frequent maintenanceLow maintenance
CheaperExpensive (once)
Easy to installHard to install
Inefficient (when rusty)Efficient
Common ringsCustom sprockets
4,000-7,000 km9,000-16,000 km

It took years of research and many attempts to make belts work. Considering the time and energy saved, carbon drive is worth the investment for serious biking. But coming to this conclusion is not easy. Factor in service expenses at the start when you go for cheap and quick.


I ended up building a new website. This time, using Next.js, React, and Tailwind UI. About as complex as the earlier setup. Still Node, so what’s the point?

I did the engineering part.

  1. Defined engines in package.json (node 20 lts)
  2. Evaluated points of failure: my code, dependencies, runtime, platform
  3. Exchanged time for money (Tailwind UI)
  4. Prepared myself for service work

Final notes

The real challenge is keeping a balance between simplicity and functionality. Trade some pace and hype for stability. It is tough, and it takes time. But as a reward, you gain expert knowledge in the process.

Make it simple.