Code Polemic Skills Philosophy Craftsmanship Software-Engineering

Keeping it simple is hard

There are actually few things in software development that are harder than keeping things simple. Complexity lurks around every corner. Reducing it, and in turn reducing technical debt – how to avoid and get rid of it – is one of, if not the, foundational challenge software engineering faces.

You can read lots of blog articles, books, and watch conference talks. At the core, most of the discussions and opinions are about finding ways – methodologies, technologies, and processes – to reduce complexity and keep things simple. Unfortunately, humans' second most impressive skill, after solving their current problems, is creating future problems for themselves.

Your Ability to Write and Maintain Complicated Code Doesn't Impress Me (Anymore)

I've been around in software development for quite a while. After working on dozens of projects and with likely over a hundred other developers in various capacities and experience levels, I can say this:

Someone's ability to churn out a lot of complicated code in a short time does not impress me. Not anymore.

To be fair, there are people who struggle to even write code at all, even at a basic level. But those usually don't work as dedicated software developers for long. For those that do, learning any relevant programming language sufficiently well to solve most problems – say, 98% of them – is quite achievable.

Sure, some developers are better or worse in various ways. But I rarely, if ever, see people who can't eventually find some solution to a typical software development problem. It might take them a lot of time. They might need to copy-paste extensively from Stack Overflow. The performance might be terrible, it might not be portable, it might be buggy as hell in edge cases, and worst of all, barely maintainable, even by the original author.

But they will produce something. And it will be released. Because product management and the customers are desperately waiting for it. There can't be any further delays! And you can always buy more hardware to run it on if the performance is bad, right? The common refrain is, "We will fix it later" – the lie developers tell themselves so they can sleep at night.

Meet ...

The Hyperproductive Hacker

Often molded by intense pressure to deliver, these kinds of developers didn't have a lot of time to reflect on their patterns of how they work and what they work on. These hackers are very fast and productive in the short term and will be able to solve a wide variety of problems very quickly if they are talented. When choosing the path for their skill tree, they put almost all their skill points in "Speed," "Damage," and "AoE" – to use a gaming analogy.

Overall, this is a great skill set—for prototyping, tech evaluations, demos—that sort of thing. Great when you work alone or with very few people.

In my experience, you'll often find people like this in startups. And they are absolutely needed there, initially. They aren't that rare though; I've seen a few of them. This approach works because once you've settled on a system to work in and don't change it much, you can focus solely on getting things done in a minimal fashion and as quickly as possible.

It often stops working, however, when the environment changes or things need to scale. That could mean something as simple as leaving the prototype phase, or an increasing number of customers, platforms, or releases.

Because unfortunately, and in many ways similar to inexperienced developers, these very productive people still leave a mess behind every time they shift their focus to the next important and exciting task. And unlike hardware, you really can't scale people as well. You might think you can just hire more of these hackers, but they ironically hate to work in other people's messes and prefer their own. The only thing that they despise more than cleaning up their own messes is cleaning up other people's messes. In that sense, they are often fully aware of the problems with this style of working but have developed the (erroneous) mindset that this is the only effective way to work under pressure.

The result? Other people will experience quite the amount of suffering due to this phenomenon because the original hacker has already moved on and is needed somewhere else. They might need to interface with it, deploy it, test it, and experience all the trouble one can have with a hastily crafted anything. And even if the original hacker is available and forced to do the maintenance themselves, you are in trouble. Because they HATE that, and they have no time for that either. So it won't be maintained any more than absolutely necessary.

If this goes on for too long, technical debt builds up until the organization is forced to hire some...

Software Engineers

Yes, "software engineer" is a generic term that is often applied to everyone that writes code. But I'd like to rebrand it to actually mean people that are committed to engineering principles like simplicity, reliability, and safety. There aren't any truly universally accepted principles of engineering, but if you look up what different organizations of engineers say about that, you won't find one thing as item one, if at all: Speed. What you do find at the very top of any attempt to define the principles of good engineering is: Simplicity. And for good reason.

For every project as a whole, and for every part of it, a decision should be made about what matters most. And that can change too. You must anticipate the future to some degree because many mistakes have massive consequences if not fixed early. And you'll find that nowadays, pretty much everything that the world gets to see and interact with must put a large emphasis on safety, reliability, and adaptability—and for all of that, simplicity is the absolute best you can do.

When you implement, you’re not just writing for the machine. You’re writing for everybody that maintains and interacts with it. If you’re the kind of person who loves writing complex code, chances are you also love creating problems for your future self (and everyone else). That’s not clever - it's the opposite.

The Hidden Superpowers of Simple Code

So, if churning out complex code isn't the goal, what is? And why is "simple" so powerful? It's because simple code isn't just "easy to understand" – though that's a huge part of it. Simple code has actual superpowers. Primarily, it's easier to reason about. When code is simple, you can hold more of it in your head, trace logic without extensive deciphering, find bugs faster, understand the implications of changes more clearly, and onboard new team members with less pain. Simple code is also more robust. Complex systems inherently have more interacting parts and potential points of failure. Simplicity minimizes these, often translating directly to fewer bugs and more reliable software because every if statement, loop, or abstraction is a place where things can go wrong. Furthermore, it's easier to change (adaptability). As business needs evolve and bugs are discovered, simple code is far easier to modify, extend, or refactor. Complex code, with its tangled dependencies, becomes brittle, where changing one part can cause unexpected breaks elsewhere. Often, simple code is more performant or at least easier to optimize. While complex algorithms are sometimes necessary for raw speed, simple code usually makes bottlenecks more obvious. Optimizing a labyrinthine codebase is a nightmare; you spend more time understanding than improving. Finally, and crucially for any business, it's cheaper to maintain. Less time spent deciphering, debugging, and refactoring complex code means lower development costs over a project's lifetime. The initial "speed" of a hyperproductive hacker is often dwarfed by the long-term maintenance burden. Simple code pays dividends.

These aren't trivial benefits. They are the bedrock of sustainable software development. The "hyperproductive hacker" might win the sprint, but the engineer focused on simplicity wins the marathon – and delivers a product that doesn't collapse a few miles down the road.

The Hard Craft of Keeping It Simple

If simple is so great, why isn't all code simple? Because writing simple code is, ironically, hard. It's a craft requiring discipline, foresight, and a willingness to resist seductive complexities. A key struggle is resisting premature abstraction or optimization. It's tempting to build for hypothetical future problems or optimize before identifying bottlenecks. Principles like "YAGNI" (You Ain't Gonna Need It) and "KISS" (Keep It Simple, Stupid) are vital; true simplicity often means solving today's problem straightforwardly. Then there's the allure of cleverness. Writing dense, "clever" code can be satisfying but is often the enemy of simplicity. The goal isn't to impress with obscure language features but to write code easily understood by everyone, including your future self. Deep understanding is also a prerequisite. To simplify something, you must understand it deeply. Superficial understanding leads to complexity. Distilling a problem to its essence for an elegant solution requires more thought, not less, often by repeatedly asking "why." The craft also demands the courage to refactor and delete code. The simplest solution might only appear after building something more complex. Recognizing this and being willing to refactor or rewrite is crucial, fighting the "sunk cost fallacy" that makes developers hesitant to discard invested time. Saying "no" is another important aspect. Complexity often creeps in through ill-considered features or requests. Pushing back, asking for clarification, and questioning the value of added complexity versus its cost is responsible stewardship of the codebase. Lastly, like any craft, time and experience are essential. Learning to write simple code comes from experience with complex systems, recognizing patterns, and developing an intuition for maintainability. There are no shortcuts.

Keeping code simple isn't a passive activity. It's an active, ongoing effort, constantly asking: "Is there a simpler way?" and being willing to do the hard work to achieve it.

The Organizational Blind Spot

Even with individual efforts, organizations often inadvertently sabotage simplicity due to systemic biases. A common issue is rewarding firefighting and visible complexity. The "hero" fixing a burning mess (often self-inflicted) gets noticed more than the developer whose simple, robust system prevents crises. Invisible success—the absence of problems—often goes unpraised. Misunderstanding productivity also plays a role. Measuring output by lines of code or features shipped can incentivize quantity over quality, discouraging time spent on simplification. A developer reducing code via refactoring might appear less "productive" by naive metrics, despite adding long-term value. The "resume-driven development" trap can lead developers to use new, complex technologies for CV-building rather than project needs. A simpler, familiar technology might be better but less exciting. Short-term versus long-term thinking is another factor. Pressure to deliver now often overrides maintainability concerns. Quick, complex hacks meet immediate demands, but the technical debt is a future problem, especially with high turnover or when decision-makers don't feel the consequences. A lack of technical leadership or mentorship that champions simplicity allows complexity to take root. Senior engineers must lead by example, enforce standards, and explain the why of simple design. Finally, organizations often underestimate the cost of complexity. Increased bugs, slower development, difficult onboarding, and burnout are hidden costs that don't appear on a balance sheet until a system becomes unwieldy or requires an expensive rewrite.

Organizations valuing simplicity must cultivate an environment that recognizes and rewards it. This means changing productivity metrics, celebrating preventative work, and aligning incentives with long-term system health, not just short-term feature output.

Comments

Loading security question...
This name is not protected - only the secret is
Also makes your name unique
No comments yet. Be the first to comment!