BACK

0 m
0 words

When Simple Code is Better than Perfect Code

We’ve all been there. You start a new project, and you’re determined to "do it right" this time. You spend the first week setting up Core, Application, Infrastructure, and Domain layers. You’ve got interfaces for your interfaces. You’ve followed every SOLID principle to the letter. You’re a "Clean Architecture" god.

Then, three months later, you need to add a single is_active boolean to the user profile, and you have to touch seven different files just to make it happen.

Congratulations: You’ve built a masterpiece of engineering that is a nightmare to actually use.

The Over-Engineering Trap

In the world of full-stack development, "Clean Architecture" is often sold as a silver bullet for scalability. But here’s the cold, hard truth: Most of the apps we build will never reach the scale that justifies that level of abstraction.

When you’re a full-stack dev building an MVP or an admin panel, your biggest enemy isn't "messy code"—it's time-to-market. * The Database Myth: We’re told to abstract the database so we can "easily switch from PostgreSQL to MongoDB." Guess what? In 15 years of dev work, I’ve seen a team switch their primary database exactly zero times.

  • The Boilerplate Tax: Every layer of abstraction you add is a tax you pay every time you want to add a feature. If your architecture makes a simple CRUD operation feel like heart surgery, your architecture is failing you.

What "Simple" Actually Looks Like in 2026

In 2026, the best architecture isn't the one with the most folders; it's the one with the shortest distance between a user's click and the database.

  1. Colocation over Separation: Keep your logic where it lives. If a function is only used by one API route, put it in that file. Don't hide it in a services/utils/helpers/logic.ts file that you’ll have to hunt for later.

  2. Server Actions are a Gift: If you're using a framework like Next.js, embrace Server Actions. Bringing your backend logic directly into your component flow isn't "dirty"—it's efficient. It eliminates the need for redundant API boilerplate.

  3. Lean Data Models: Stop creating "Data Transfer Objects" (DTOs) for every single request. Use your ORM’s types (like Prisma or Drizzle) directly until you actually have a reason not to.

The "Smell" of Over-Engineering

How do you know if you've gone too far? Ask yourself these questions:

  • Do I have to open more than 3 tabs to understand how a single button saves data?

  • Am I writing interfaces for classes that only have one implementation?

  • Am I building "extensibility" for features I haven't even thought of yet?

The Verdict: Ship First, Refactor Later

"Clean code" is code that is easy to read and easy to change. Ironically, highly abstracted "Perfect Code" is often the hardest to change because the dependencies are so tangled in a web of interfaces.

Don’t build a cathedral when a sturdy shed will do. Write the "dirty" code that works, gets users, and makes money. You can always refactor a successful app. You can’t refactor an app that never launched because you were too busy building a "Domain Driven Design" for a landing page.

Stay simple. Stay fast. Get it shipped.

© Victor Westelynck

Barcelona, Spain

20

°C

© Victor Westelynck

Barcelona, Spain

20

°C