Skip to main content
  • English
  • Български
contact@kotito.com
Clean architecture layers illustration
#Web development#Guide

Clean Architecture in Practice — Lessons From Our January Reset

Every January we audit our codebases. This year the exercise confirmed what we already suspected: the projects with strict layer boundaries were the ones that survived change.

January is audit season at Kotito. Every project that shipped the previous year gets a fresh look — not to nitpick, but to learn. What held up? What crumbled the moment requirements shifted?

This year the pattern was unmistakable. The projects built with clean architectural boundaries — clear separations between data access, business logic, and presentation — were the ones clients could extend without calling us back.

Why layers matter more than frameworks

A framework gives you structure. Architecture gives you freedom. We have worked with Next.js, Astro, SvelteKit, and plain Express backends. The framework changed every time. The principle never did: dependencies point inward.

Your presentation layer depends on your business logic. Your business logic depends on your data interfaces. Nothing depends outward. When you respect this rule, swapping a database or a UI library becomes a contained operation instead of a project-wide rewrite.

The dependency rule in a real project

Take our work on a cultural events platform. The original build had API calls scattered through React components. When the client wanted to switch from a REST backend to a GraphQL API, every component needed changes.

The rebuild isolated data fetching into repository modules. Components received data through props. When the API changed again six months later — this time to a headless CMS — only the repository layer needed updating. Zero component changes.

Practical boundaries for small teams

Clean architecture does not require enterprise-level abstraction. For a typical web project we enforce three rules:

One. Pages and components never call APIs directly. They receive data as props or through a data service.

Two. Business rules live in plain functions with no framework imports. They can be tested in isolation with a simple test runner.

Three. External services — APIs, databases, analytics — are accessed through adapter modules that export a stable interface.

These rules fit in a README and take ten minutes to explain to a new developer joining the project.

What we got wrong

In one project we over-abstracted early. We built interface layers for services we had not integrated yet, guessing at their APIs. When the real integrations arrived, half our interfaces were wrong and needed to be rewritten.

The lesson: abstract what exists, not what might exist. YAGNI still applies, even in clean architecture.

The audit outcome

Of the six production projects we reviewed, the two with the strongest architectural boundaries had the lowest maintenance cost and the highest client satisfaction scores. They were also the easiest to hand off to other developers.

Clean architecture is not about purity. It is about giving your future self — and your client’s future team — the ability to change direction without starting over.