When building, don’t add. Subtract.

Jonathan Suzuki
Qulture.Rocks Product Blog
4 min readSep 16, 2021
A black and white picture of a building under construction, with a tall crane in the center. The perspective is from below, highlighting the tallness of the crane.
Photo by Ben Allan on Unsplash

Imagine you are going about your day during your work and you are assigned to a task that tells you that you have to add a button to the navbar of your website. This button is going to receive an onClick that will open a support chat on the page and should be placed between the “Products” and the “About” links. You think “Huh this should be a piece of cake”. Sounds like a simple enough task right?

You go and take a look into the code and you see this:

[Dont add, subtract] Navbar example 1 (github.com)

How would we go around adding a button here? It already has links… The task could’ve been add a link 😅, it’s always the edge cases…

What is your first instinct? Take a few seconds to formalize it.

While you think of it, I went around the office and asked a few coworkers their first instinct and got some answers.

One of them suggested:

Maybe change the interface to something like [{component}, { label, href }]

[Dont add, subtract] Navbar interface (github.com)

And then update the map to see if it received a component or a link. If it has a component, I’d render the component and if not would render the link as usual.

I personally have been in this situation and my first instinct was:

I’m going to add an onClick to the item interface, if it has an onClick is a button, if it has an href it is a link. Something like:

[Dont add, subtract] Navbar solution adding (github.com)

If your first instinct was also to think: “maybe I can add a type, or X Y Z” you are not alone, we have a tendency to keep adding on previous abstractions.

The article cited in the video explains that most of the times we fail to consider the existence of a solution that subtracts. In the experiment conducted participants were asked to stabilize the top of a lego structure, adding pieces would cost 10 cents and removing would cost nothing. While the optimal solution was to remove one block, only when the participants were reminded that “removing pieces was free” researchers saw a 50% increase on the use of solutions that subtracted.

In our example if you weren’t paying attention you might have not even noticed there was an abstraction in place, not all abstractions have complex structures or fancy patterns around it! In this case it was just our little array of objects.

Imagine we went with the solution of where we inferred the item type through href and onClick. Now we discover that we need to disable the support button outside working hours, do we add an disabled prop in the item? Can links be disabled? With every modification our abstraction starts to grow and every time it grows, it becomes harder and harder for the next developer to understand it. And when the abstraction passes a certain point it becomes more daunting to consider what was probably the best option at first: what if we remove the abstraction?

Some of my coworkers were able to see right through it, and one even made a very good observation:

I don’t know, I think I’d give up on this abstraction of an array of links, because it can start to become kinda bizarre to determine “what even is an item” with some really bizarre ifs internally.

My guess would be something like

[Dont add, subtract] Navbar example subtracting (github.com)

Which was pretty much the answer I was fishing for, removing the abstraction allows for better expansion and reduces the cognitive load of the next developer.

Some may ask: was the first abstraction, the array of links, wrong? To that I’d say probably not, it was perfectly fine before our new requirements, there are no villains in this story. If the product changes the code should keep up with it.

When I first started programming I’d always thought I’d be adding things, but turns out that sometimes removing can be just as good.

--

--