Following our introduction, we are moving to the very center of the “onion” diagram. In this second part, we will explore Entities, which represent the core reason your application exists.
Clean Architecture Entities: The Heart of Your Application
In the previous article, we discussed the high-level layers of the “Onion Architecture.” Today, we dive into the innermost circle: Clean Architecture Entities. This layer is the most stable and should be the least likely to change when something external (like a database or a UI framework) changes.
What are Entities?

Entities encapsulate Enterprise-wide Business Rules. An entity can be an object with methods, or it can be a set of data structures and functions. It doesn’t matter, as long as the entities can be used by many different applications in the enterprise.
If you don’t have an enterprise and are just writing a single application, then these entities are the business objects of the application. They represent the “Real World” concepts of your project—such as a User, a Product, or an Order.
The Core Rule: Total Independence
The most important thing to remember about Clean Architecture Entities is that they know nothing about the layers outside them.
- They don’t know about your database.
- They don’t know about your API.
- They don’t even know you are using Flutter.
This independence is what makes them “clean.” You should be able to take your Entity classes and use them in a command-line tool or a web app without changing a single line of code.
Entity vs. Model: What’s the Difference?
This is a common point of confusion.
- Model: Usually contains logic for data transformation, such as
fromJson()ortoMap(). It is tied to the Data Layer. - Entity: A pure class containing only the data and business logic. It should not have any mention of JSON or third-party libraries.
Practical Code Example
Let’s look at how a simple User entity looks in Dart.
// Domain Layer: entities/user_entity.dart
class UserEntity {
final String id;
final String name;
final String email;
final bool isPremium;
UserEntity({
required this.id,
required this.name,
required this.email,
this.isPremium = false,
});
// Pure business logic: Checking if a user can access premium content
bool canAccessPremiumFeature() {
return isPremium;
}
}
Notice that there is no factory UserEntity.fromJson here. If we need to convert JSON from an API, we do that in a Model in the Data Layer and then map it to this Entity.
Conclusion
Clean Architecture Entities are the foundation of your project. By keeping them pure and independent, you ensure that your core business logic is protected from the “noise” of external frameworks and tools.
In the next part, we will look at how to coordinate these entities to perform specific tasks using Use Cases.
Link to the SOLID Principles Wikipedia page, as Entities rely heavily on the Single Responsibility Principle.