August 4, 2025

Software architecture is about spending abstractions

DPC wrote a great blog post about how you can’t just avoid complexity. I think it’s definitely worth a read if you haven’t already. I agree with his point about complexity being a currency” and I extrapolated it to the domain of software architecture.

One of the biggest mistakes I see in modern codebases is the idea of perfect abstractions”. That is to say, that everything has an abstraction built-in, regardless of the value the abstraction provides. Senior engineers love to build software this way: highly abstracted and future-proofed, something that is hard to criticize in a PR, and lets the engineer go home with the idea of having done things the objectively correct way”.

Building software this way has many consequences. Often the idea of future-proofing is wrong all together. Problem domains change all the time. And it tremendously slows down development. Developers require more time to learn the system, and more time to implement changes. With bad abstractions, development can quickly grind to a halt.

The most innocuous everyday example I can think of is the locale / content abstraction.

The content abstraction is simple: put content (the words on the page) into its own interface, and then have the app access the interface instead of the literal content.

Instead of <div>{"Hi Nate!"}</div> you might have <div>{content.home.greeting}</div>.

There are good reasons for doing this. One of them is to support i18n. A content abstraction lets you swap the text in the app behind a language config. Another is to support overriding content from other sources. For example, it’s not uncommon to have a CMS like Strapi which houses all of the content, to be accessed by a separate content team without requiring developer intervention.

But creating a content abstraction should be done for a specific purpose. Not simply as a best practice” or a future proof”. Now, simply changing button text requires understanding the inner workings of a new abstraction. It may require understanding how content is loaded into the app, how the language setting interacts with the locale files, and where and how those locale files are right-sized: are they broken out per feature, per language, per screen? Did updating the value for my button also update it in other places? Is there a way to prevent the CMS overriding the content? Are there different environments around that CMS? Are there ways to override the content from the app instead of the CMS? Or even simply: what’s the DSL to display dynamic text like with template literals?

And the content abstraction is the easiest, more junior-friendly abstraction there is. It’s usually good to have a content abstraction. But you can see that even the simplest of abstractions can impact development velocity.

Like DPC said, complexity, or in the case of software - abstractions - are like currency. You have to spend it wisely!



Copyright Nathanael Bennett 2025 - All rights reserved