Software is a superpower. Complexity is its kryptonite.

Software was my first love. It still is. It's the purest medium for creativity I know. Give me a computer and an idea, and I can sit down in the morning with nothing and have something real by evening. Something that solves a problem, automates the tedious, or helps someone see what they couldn't see before. To me, developing software is the closest thing to a superpower.

I've built pricing platforms, insurance risk systems, banking software, and governance platforms used by some of the largest banks and insurers in the world. Some of my best lessons came from sitting with customers and seeing firsthand how they used our software. There's no better way to build it. You see what helps people. You see what frustrates them. Sometimes, you discover that the thing your team spent months perfecting isn't the thing they needed most.

And yet, over the years, something began to bother me. I was spending less time doing what I loved about software, and more time on work that pulled me away from it.

I kept asking myself: Is there a better way to build software?

What subtraction is

  • Subtracting unnecessary complexity
  • Subtracting dependency bloat
  • Subtracting barriers to understanding
  • Subtracting development friction

What subtraction is not

  • Cutting corners
  • Losing capability
  • Rejecting open source
  • Simplifying at any cost

What we subtract, we give back to the people who matter most: the users who rely on software and the developers who bring it to life.

Day two, and the new developer is still stuck

Imagine a new developer joins your team. You give them a semi-automated guide to set up their development environment. It's day two, and they're still stuck. Now they're wondering: Is this a silly question? Am I asking too many questions? Should I have figured this out by now?

The problem isn't the new developer. The team probably never had time to make setup a one-click experience. New features, bug fixes, security patches: there's always a fire to fight, and developer experience waits. That's Conway's Law at work. Your software, and how your users feel about it, will mirror your team's firefighting culture. You've just spotted something important.

A painful developer setup is often the tip of the iceberg. If getting the code running is this hard, what is it like to change it? And this complexity doesn't stop at the developer's desk. It finds its way into deployment, upgrades, troubleshooting, and customer onboarding. Customers end up paying for it in time and money.

Software should be safe to change. When code feels like a minefield, developers stop touching it. New code piles on top, and old code never leaves. It doesn't have to be this way. AI makes understanding, refactoring, and rewriting code dramatically faster. Getting there has never been cheaper.

So when a new developer struggles on day two, don't just improve the setup guide. Ask what the struggle is telling you about the software.

Unsubscribing from dependency hell

Picture a business with an idea. They want software that's a true ally: beautiful, secure, robust, fast, and intuitive. Something that has their back. Instead, they often inherit a bloated footprint, a fragile core, and a frustrating refrain when they ask for critical features: "We'll put it on our roadmap." I'll admit, I've been on the receiving end of that call myself.

Underneath much of this is one habit we rarely question: we've become addicted to dependencies. You need one small capability, so you add a package. It brings its own dependencies, which bring more dependencies. Before long, your application relies on hundreds of packages, and nobody on your team has examined most of them.

Every package you add is code you didn't write and can't fully see. When a vulnerability lands, the roadmap waits. Your engineers spend days patching someone else's code instead of building what your customers asked for.

So here's a question worth asking: How much of each dependency do we actually use? If you need one percent of a package, is bringing in the other 99 percent worth it? Sometimes, writing that small piece yourself is the simpler choice.

I deeply respect open source. None of us would be here without it. This isn't about abandoning it. It's about using it deliberately, not reflexively.

Before adding another dependency, ask yourself: Am I solving a problem, or importing a new set of problems along with it?

Two tests for every dependency

Start with the business need, not the tool. Before adding any code, visualize the overlap like a Venn diagram: what is actually needed versus what the package delivers. If a system is carrying a massive payload of extra code just to use a sliver of functionality, it's time to take a step back. Whatever survives that first filter must pass two non-negotiable tests.

1. Is it small, focused, and built to do one job well?

A good tool should take hours or days to comprehend, not weeks. When software tries to be everything to everyone, it introduces invisible attack surfaces.

Consider Log4Shell, the infamous 2021 vulnerability. The flaw wasn't in basic logging; it was buried in an obscure lookup feature that allowed arbitrary code execution through a text string. The entire tech industry felt the blast radius of a feature most developers didn't even know existed. The lesson is clear: complexity demands scrutiny.

Every capability you don't use is still an edge case you have to defend.

2. Is the underlying concept slow-changing?

Abstractions decay quickly; foundational paradigms endure. Take SQL. It has survived for decades as the bedrock of data manipulation because it is grounded in relational mathematics. Meanwhile, we've watched waves of trendy Object-Relational Mapping (ORM) frameworks and abstractions come and go.

My rule? Write the raw SQL. Keep the data access layer visible and explicit. Don't introduce a heavy, opinionated framework just to hide a language that is already clean and simple. The native queries you write today will easily outlast whichever framework is fashionable this quarter.

The more rope a framework gives you, the faster you wrap your team in someone else's architectural constraints.

The democratization of knowledge

There's a human side to this that matters deeply. At heart, every engineer wants the same thing: to do meaningful work and be proud of what they build. What stands in their way is rarely a lack of talent or motivation. It's the crushing weight of accidental complexity.

Complexity disenfranchises. It locks knowledge away in the minds of a select few, leaving teams entirely dependent on the one person who understands a mysterious subsystem, an elaborate build script, or a framework no one else dares to touch. When code becomes an elite secret, collaboration dies.

Simplicity democratizes. It lowers the barrier to entry, giving everyone on the team the confidence to contribute, debug, and take genuine ownership. When software is simple, engineering becomes a collective triumph rather than a gatekept privilege.

This human impact extends directly to your users. They should never need a specialist, a training manual, or a complex workaround for an ordinary task. Software is meant to expand human capability, not tax it.

Ultimately, subtraction isn't just about deleting lines of code. It's about removing the barriers between people and what they want to accomplish.

Making software humane

We build software to automate the tedious and the repetitive, freeing people to focus on what truly matters. As creators, we deserve that same freedom. That's exactly why I started Subtract Software.

I still deeply love this craft. I love the exact moment an idea becomes real, the breakthrough when a difficult problem clicks, and the relief a customer feels when our tools actually make their life easier. I want more of those moments—both for the people who build software and the people who rely on it.

This isn't a call for less ambition or diminished capability. It's a refusal to let unnecessary complexity stand between us and the things worth building.

Let's subtract the noise, make room for the people, and bring the joy back to engineering.