No Perfect Solutions

There are no perfect solutions, there are always trade-offs.
Expecting perfect solutions – checking all the boxes – is a common mistake projects and their sponsors make. One cannot have it all and have to give up on some of the requested features and functions.

Solutions to complex problems always involve trade-offs. There lies the challenge – among the different, less-than-perfect options, which one gives the most and compromises the least?

If you like this topic, you might be interested in listening to the episode – The short list – from Seth Godin’s podcast – Akimbo.


Use TypeScript…

Working with others on a JavaScript codebase?

Use TypeScript instead and benefit from static typing.


Getting on the same page using abstraction

As engineers, we constantly grapple with the challenge of creating solutions that are efficient, scalable, and maintainable. A key aspect that can make or break our projects is the ability to establish a common understanding among team members. In any team, individuals possess varying mental models, skills, and experiences, leading them to arrive at different abstractions. These divergent abstractions may introduce misunderstandings and hinder effective collaboration. Abstraction serves as a bridge that enables team members to navigate the diverse mental models that shape their perceptions of concepts.

Each team member arrives to a different abstraction (A, B, C, D) from entirely different angles.
The goal is to get everyone to arrive to a common abstract understanding (△). Use that to drive the conversation and problem solving, then approach the concrete solution (E) from the same starting point.


Software architect working with a team of four on a complex problem. The four people think about the problem and the solution in different ways:
(A) Component model diagram in LucidChart
(B) Class model diagram using UML
(C) Pseudo code
(D) JavaScript playground on

Led by the architect, eventually the team arrives to a common, abstract view (△) – a one-pager annotated diagram using C4 in Mermaid.

Team builds a web app (E) on the MEVN stack, arriving to the concrete implementation.


The ultimate goal of achieving a common abstract understanding is not to suppress individual creativity or to homogenize approaches. It creates a harmonious collaboration environment where everyone’s insights are valued and leveraged. Additionally, it fosters a sense of collective ownership and responsibility for the project. Rather than working in isolation, team members become invested in the overall success of the solution. It promotes clarity in requirements interpretation, reducing the likelihood of misunderstandings and rework.

As a result, the team’s productivity improves.


Slow Work Needs Time

Some work is not meant to be done quickly and not meant to be done by a specific date either.

It is not unreasonable to expect output and results in time to be able to progress, but slow work needs time.

Pin a deadline on or timebox an activity and be prepared to make trade offs.

Trade offs could mean less than ideal.
Perhaps “less than ideal” is what’s needed for the work to be done.


For an even longer (much longer) read, check out Driving engineers to an arbitrary date is a value destroying mistake from Gandalf Hudlow on



Abstraction is a recurring theme in my work.
While it is second nature for some, most folks have too strong of a footing in concrete 😀

Everybody can do abstraction. It is a skill, it is a mental muscle that needs training. Applying it regularly to situations and using it purposefully is a different matter. A short, visual explanation on what I mean by applying abstraction purposefully.

  1. The arrow pointing away from concrete indicates the idea of abstracting away. The further we are, the more abstract the concept becomes.
    Arrows shooting out to different directions signifies that abstraction can happen along many different aspects.
  2. The arrow pointing towards the centre indicates reducing abstraction. The closer we are to the centre, the more concrete it gets.
  3. Exploring other aspects while remaining on the same level of abstraction.
  4. Starting from something concrete and walking thorough levels of abstraction before descending back does not necessarily arrive to the same concrete point.

The irony of explaining abstraction in an abstract manner is not lost on me. Future posts will include more concrete and practical points.


  • You are the software architect working with a team of four on a complex problem.
  • The 4 people think about the problem and the solution in different ways
    A. Component model diagram in LucidChart
    B. Object-oriented class model diagram using UML
    C. Object-oriented pseudo code
    D. JavaScript playground on
  • Eventually the team arrives to a common, abstract view
    △ One-pager annotated diagram using C4 in Mermaid
  • Implementing the solution
    E. Building a web app on the MEVN stack
Engineering Hives and Silos


The story goes…

Business X has been using a software package for the last 20+ years to perform a critical, maybe even the most critical, function of the business.

20+ years ago this package used to be an off the shelf, install on an office PC, double-click to launch in Windows type of application. It probably looked rubbish but had a menu with 3+ levels to navigate dozens of screens with 20+ fields each to manipulate. There were only a few people that could learn and knew how to use it for some very specific tasks.

10+ years ago the vendor of that package found it easier – meaning no install, no update, no office PC – to put the same software on a bunch of servers and let users access it remotely (RDP).

Today many of these applications are still running businesses, mostly because they are cheap or because over time they became a monopoly.

Innovation at these vendors, and the businesses using them, would have stopped, if it wasn’t for a new movement.
Reluctantly, the vendors slowly added a new type of access – API – to their packages.
These dumb API-s would often look like an XML version of the screens they represent.

Business X realised they have a new option.
Rather than paying for an expensive 20+ years old application running remotely they can pay a lower fee for accessing the API.

Projects are in abundance making the transition – under the banner of Digital Transformation – from remote desktop Windows applications to web based, API led solutions.

There are so many ways these transformation projects go up in smoke.
One is where business X insists on rebuilding the same screen flow from the old desktop application.

Is this Digital Transformation? No.
Maybe modernisation? Hardly.
It is simply cost avoidance.

Engineering Hives and Silos

Tech Stack Bingo

Tech Stack Bingo is when a business has a portfolio of, seemingly random, tech they acquired (sold to) over the years.
As the projects roll in, the needs mark a match with an existing tech.
The closer the match the better. They win if no tech lingers on without a project and nothing comes in needing a new tech – BINGO.

Some sorry businesses try to cheat their way by forcing some close enough tech on the project.

This is where disaster strikes. It happens more often than one would expect, for example:

  • somebody bought the tech and now need to use it, cannot lose face (or the job)
  • everything is done with the one and only tech the organisation has some skills in (nail and hammer)