Ryan Chandler

Don't Subscribe to Complexity

3 min read

tl;dr Complexity is a silent killer. It sneaks into projects under the guise of best practices, cutting-edge frameworks, and future-proofing. More often than not, it actually causes more problems than it solves.

Here's the problem with complexity. Many developers build solutions for problems they don't have yet. They anticipate scaling issues, edge cases, or future requirements that will likely never materialise. Instead of focusing on solving the problems at hand, they overengineer their systems, adding unnecessary layers that slow down development and introduce unnecessary cognitive overhead.

Abstractions are powerful, but overdoing it tends to make systems harder to understand and maintain. Layers upon layers of interfaces, abstract classes, factory patterns is really just glorified indirection. If a developer needs to dive neck-deep when clicking through classes to find a method implementation or definition, the abstraction has failed.

Something else that causes a lot of problems is "trend-chasing". New frameworks, libraries, and architectural styles appear all of the time. Don't get me wrong, some of them do bring real benefits to the table, but the majority of them are just hype. Adopting a microservices architecture when a monolithic approach would do, or switching to a brand-new JavaScript framework because it's trending on GitHub. You should be choosing the tools that fit your needs (which could be microservices or domain-driven design). You shouldn't be chasing the latest and greatest – give it some to grow – new doesn't always equal better.

Here's my 5 step guide to reducing unnecessary complexity.

1. Keep it simple, stupid (KISS)

Focus on solving today's problem. Don't think about the imaginary ones of the future. The simplest solution that works right now is often the best.

2. You ain't gonna need it (YAGNI)

Don't build unnecessary complexity in the name of flexibility. Adding infinite levels of abstraction for a future use-case that may never come is wasteful. Build what is needed for now and iterate when the requirements change.

3. Optimise for readability

Your code should be easy to understand, not just for you but anyone who has to maintain it. Clear, well-structured and self-explanatory code should save you from those nightmarish debugging sessions.

4. Resist the hype

Choose tools and architectures based on necessity, not popularity. Just because somebody said "X is cool", doesn't mean you should be using X. Prioritize stability and simplicity over following the latest "cool kids" thing.

5. Refactor as you go

Start simple and improve things as you go along. Avoid prematurely optimising or restructuring a system before it's absolutely necessary. Small, incremental improvements over time lead to cleaner, more manageable and easily reviewable code.


Complexity doesn't make your code more sophisticated – it makes it harder to work with.