Entity types

Last updated on
30 December 2025

Drupal distinguishes between two fundamentally different entity types: content entities, for example, nodes, taxonomy terms or users and configuration entities like user roles, site settings or image styles.

Entity Types Overview

Modern Drupal (8 and above) knows two basic entity types:

Both are structured, typed objects, but they serve different purposes: content entities store user-facing data in the database, while configuration entities store system-level settings that control site behavior and can be exported and imported via Drupal’s configuration management. In practice, content entities are manipulated primarily by end users, whereas configuration entities are usually managed by developers and administrators.​

Content Entities

Content entities consist of configurable fields and base fields, support revisions and translations, and are stored in database tables where each field may have its own table for efficient data management. Typical examples are nodes, taxonomy terms, users, comments, and files, which end users can create, edit, and delete through the site’s interface as part of normal content interaction.​

Configuration Entities

Configuration entities represent items such as content types, views, user roles, image styles, block types, menus, and date formats. Unlike content entities, they are stored as configuration objects and are designed to be exported and imported across environments, making them essential for keeping development, staging, and production in sync. Configuration entities support translation but do not use the Field API for user-configurable fields; their structure is defined in code, which keeps them predictable and stable for configuration management workflows.​

Modern Drupal vs Drupal 7 

  • Drupal 7 - entities were generic stdClass objects.
  • Drupal 8 - entities are now specifically typed objects, with each entity type defining a class that will be used for instances of the given entity.

Visualization of entity classes

To get a complete picture of the entities in modern Drupal 8 and above we can review the following diagram. This represent the entity classes. To view open in a new tab:
Entities diagram

Requirements

Entity classes must be placed in the Entity sub-namespace of the module that provides the entity type, e.g. \Drupal\[module_name]\Entity. This means entity class PHP files may be found in a module's src/Entity directory.

The docblock for the class must contain an EntityType annotation that defines the metadata for entities of that type. These include things like the entity type's label, controllers, tables, etc. For a documented list of all the available metadata properties, refer to the \Drupal\Core\Entity\Annotation\EntityType class.

Naming

Entity type names should be prefixed with the module name if the entity type and module name aren't the same. Prefixing the entity type's class itself is not required since it lives within the namespace of the defining module, provided it is meaningful enough on its own. For example, the entity type for taxonomy terms is named taxonomy_term and the class name is Drupal\taxonomy\Entity\Term.

Interfaces

Drupal 8 recommends you type hint functions and methods with interfaces instead of classes. For example, the generic entity storage hooks type hint with EntityInterface as in hook_entity_insert(EntityInterface $entity) and the node specific storage hooks type hint with NodeInterface as in hook_node_insert(NodeInterface $node).

Entity fields / properties are often very short, storage-centric and not very self-descriptive. Additionally, content entities don't use defined properties for their fields (including base fields like the node title) at all.

Therefore, the recommended approach is to provide an Interface with documented method names. A few rules to follow when doing so:

  • Methods usually have a get/set/is or similar prefix: getSomething(), setSomething($value), isSomething().
  • Only add methods for things that other code is supposed to change. The last changed date of nodes ($node->changed) isn't supposed to be changed, so there is $node->getChangedTime() but no $node->setChangedTime() method.
  • Use self-descriptive method names, for example, the method to access $node->status is called $node->isPublished().

Discoverability

To find out which entity types a module provides, refer to the classes in the Entity sub-namespace of that module that have an @EntityType annotation, which also contains the name in the id annotation key.

When trying to find where a given entity type is defined, the first thing to look for is the prefix of the entity type. If a module doesn't follow that naming convention, then it can be found by searching for id = "$type". If the class or interface is known instead of the entity type, then the namespace of that indicates where it is coming from. 

Help improve this page

Page status: No known problems

You can: