Skip to main content

Smart UI

The Smart UI anti-pattern fuses business logic and data access into the presentation layer with no domain model, blocking testing, reuse, and safe redesign. Introduce real layering via clean architecture and DDD so the UI presents while a tested domain core decides.

The Smart UI anti-pattern (named by Eric Evans as the "Smart UI Anti-Pattern") puts business logic, validation, and data access directly into the presentation layer, with no domain model beneath it. Each screen or component handles its own rules and talks straight to the database. It is productive for trivial CRUD applications, which is why rapid-development tools encourage it — but it becomes a serious liability as soon as the domain has real complexity.

Why It Happens

Smart UI is the natural result of building screen by screen. The fastest way to deliver a form is to wire its component directly to the data and embed the rules right there. Visual builders, low-code platforms, and component frameworks reward this by making the UI the center of gravity. For small applications it genuinely works, so teams keep doing it as the system grows. Without a deliberate decision to introduce a domain layer, logic stays where features are added: in the UI. It is essentially the Magic Pushbutton scaled up to an entire architecture.

Why It Hurts

With logic spread across components, there is no domain model to express the business consistently, so the same rule is implemented differently on different screens and drifts apart. Logic cannot be tested without driving the UI, so coverage is poor and regressions common. The UI and the domain are fused, meaning a visual redesign or a platform change (web to mobile, framework upgrade) risks discarding business logic along with the presentation — a costly trap when the rules are the valuable part. Reuse across channels is impossible because nothing exists below the UI to reuse. As complexity rises, the lack of a shared model makes the system progressively harder to change.

Warning Signs

  • Business rules and calculations live inside UI components.
  • Components query the database or call external systems directly.
  • The same rule is implemented separately on multiple screens.
  • There is no layer between the presentation and the data store.
  • A planned UI rewrite is feared because logic would be lost.

Better Alternatives

Introduce real layering. Clean Architecture keeps business rules in a core that the UI calls, so presentation is a replaceable outer ring. Domain-Driven Design provides a shared domain model that all channels use consistently. The unifying principle is separation of concerns: the UI presents and collects, while the domain decides. For genuinely trivial CRUD, Smart UI can be acceptable — the key is recognizing when complexity has outgrown it.

How to Refactor Out of It

Start by extracting business logic from components into a UI-independent layer: services, use cases, and domain objects that can be unit tested. Pull data access out of the UI into repositories the domain layer uses. Consolidate the rules duplicated across screens into the new shared model, deleting the copies. Have components call the domain layer rather than implementing decisions themselves. Migrate screen by screen so the system keeps working throughout. Once a real domain core exists, the UI becomes thin and replaceable, multiple channels can share the same logic, and a future redesign no longer threatens the business rules.