KISS in Programming: Why Simplicity Sometimes Beats Clean Architecture

When I first learned about Clean Architecture, it looked like the perfect way to build software. Layers are separated, dependencies are inverted, and everything seems to make sense logically. But after looking around different projects, talking to other developers, and reading code in real teams, I started to notice something interesting sometimes, the simpler systems are the ones that actually last longer and are easier to maintain.

That’s where the KISS principle comes in.

KISS stands for “Keep It Simple, Stupid”. It’s an old design principle that reminds us not to overcomplicate things when a simpler solution would work just fine.

In this post, I want to share some observations about how simplicity in code even if it doesn’t follow every rule of Clean Architecture can be more practical, especially for small teams or early-stage projects.

The Promise of Clean Architecture

If you’ve read about Clean Architecture, you know how structured it looks. There’s the domain layer, the application layer, the infrastructure layer, and sometimes a presentation layer on top. Every dependency flows inward, meaning the core business logic doesn’t depend on external systems like databases or APIs.

It sounds great in theory. It gives a feeling of control and long-term scalability. You can replace your database easily, switch to a different API, or test your business logic without worrying about dependencies.

But here’s the thing: in practice, this structure also brings a lot of complexity especially when the project is small or the team is new to these patterns.

When Architecture Becomes a Burden

Clean Architecture is not “wrong”. It’s a solid principle. But sometimes, it becomes too heavy for the problem we are trying to solve.

Let me give a common example.

Imagine a small web app, let’s say a task tracker. You have basic CRUD (Create, Read, Update, Delete) operations, user management, and maybe a few reports. If you strictly apply Clean Architecture, you’ll end up with something like:

Plaintext
/Domain
    Entities/
    Interfaces/
    ValueObjects/
    
/Application
    UseCases/
    DTOs/
    
/Infrastructure
    Persistence/
    Repositories/
    Services/
    
/Web
    Controllers/
    ViewModels/

You write interfaces for repositories, create DTOs for every request and response, and wrap simple logic inside multiple layers of abstraction.

Suddenly, your 200-line app turns into a 1,000 line architecture.

For experienced developers, this might feel natural. But for beginners or small teams, it becomes a barrier.

Every change feels slow. Every bug fix requires jumping between five folders. Every feature looks “heavier” than it should be.

Simplicity Has Its Own Strength

Sometimes, the most maintainable code is not the one that follows every principle, but the one that people can read and understand easily.

A simple architecture doesn’t mean messy code. It just means you only add layers when they are truly needed.

For example, a small API project might just have:

Plaintext
/Models
/Services
/Controllers

No dependency inversion, no domain layer, no abstractions for the sake of abstractions.
When your code is simple, new developers can understand it faster. Debugging is straightforward. The business logic is visible not buried under patterns.

And honestly, that matters a lot more than whether it perfectly follows a diagram from a software engineering book.

The Trade-Off Between “Perfect” and “Practical”

When teams argue about architecture, it’s rarely about what’s correct. It’s about what’s appropriate.

  • For enterprise systems that live for 10+ years and are maintained by hundreds of people, Clean Architecture makes sense. It enforces discipline and consistency.
  • But for startups, small teams, or proof-of-concept projects, simplicity is power. It helps you move faster, make mistakes, and learn without drowning in boilerplate.

What’s important is to know when to stop adding abstraction. Abstraction is like salt a little makes things better, too much ruins the whole dish.

KISS in Action: Real-World Observations

When I look at some open-source projects or internal tools in companies, I notice a common trend:

  1. Successful small projects usually start simple. A few files, straightforward logic, no frameworks trying to be clever.
  2. Failed small projects often tried to copy enterprise patterns too early. The architecture was beautiful, but the product never shipped.
  3. Mature systems sometimes evolve naturally into cleaner structures over time. They didn’t start “Clean”. They became clean as the needs grew.

This shows something important: simplicity is not the opposite of cleanliness it’s the starting point. You can always refactor later when the system justifies the complexity.

Beginners Need Wins, Not Layers

For new developers, the idea of Clean Architecture can feel overwhelming. They read about dependency injection, repository patterns, DTOs, domain services, and think, “Am I even coding the right way”?

The truth is, at the beginning, you don’t need all of that. You just need to learn how to write code that works, is readable, and makes sense to you.

When beginners spend more time setting up folders than actually solving problems, the motivation drops. Clean Architecture should be a goal, not a requirement.

When “Simple” Doesn’t Mean “Sloppy”

Of course, simplicity doesn’t mean ignoring good practices. You can still write clean, readable, and well-tested code in a simple architecture.

Here are some ideas that make code simple but still professional:

  • Use clear function names. No need for abstraction if your method name already explains what it does.
  • Avoid unnecessary indirection. If one class can handle it, don’t split it into three.
  • Focus on clarity over purity. Write code that your future self can understand after three months.
  • Add layers only when you need them. For example, you don’t need a repository interface if there’s only one implementation.
  • Keep dependencies low. Every extra layer is a potential maintenance cost.

This mindset keeps your project lightweight without making it fragile.

Clean Later, Not Sooner

The main misunderstanding about Clean Architecture is thinking it must be applied from day one. But architecture should be a response to complexity, not a starting point.

Start with something simple. Once you feel the pain, when code becomes hard to change, or when multiple parts start to depend on each other that’s when you start cleaning.

You evolve your design when it earns the need, not before.

That’s the heart of the KISS principle. Simplicity first, structure second.

The Wisdom Behind KISS

The KISS principle is not anti-architecture. It’s just a reminder that architecture is not the main goal solving problems is.

Every layer, every abstraction, every pattern you add should have a reason.
If you can’t clearly explain why it exists, it probably doesn’t need to be there.

Sometimes, the best code is the one that looks “too simple” to be wrong. Because simple code invites understanding, and understanding builds confidence.

Closing Thoughts

There’s a quiet beauty in simplicity. While Clean Architecture has its place, it’s not always the best fit for every team or project. KISS doesn’t reject good design, it just asks us to be practical.

In the end, the goal is not to impress other developers with complex layers.
The goal is to solve problems, deliver value, and write code that people can live with.

Start simple. Keep it clean enough to grow. And when the time comes to refactor, you’ll know exactly why you’re doing it, not just because a diagram told you to.


References

Assi Arai
Assi Arai
Articles: 46