What Is an Entity in Drupal?
An entity in Drupal is a structured data object that stores content or configuration inside the system. In simple terms, everything important in Drupal is managed as an entity. For example, users, nodes, taxonomy terms, files, and comments are all part of the Drupal Entity system.
With the introduction of the modern entity in Drupal 8, the platform moved toward a more consistent and powerful data model. This change made it easier for developers to manage content, extend functionality, and work with structured data in a standardized way.
There are two main types of entities:
Content entities – These store actual content, such as nodes, users, and taxonomy terms.
Configuration entities – These store configuration settings, such as views, content types, and roles.
The Drupal Entity system uses the Drupal Entity API, which provides methods for creating, reading, updating, and deleting entities. This API ensures consistency, validation, and access control across all entity operations.
Understanding the Drupal Entity API
The Drupal entity API is the core system that enables developers to consistently create, load, update, and delete entities. Instead of writing direct database queries, Drupal provides a structured API that handles storage, validation, access control, and caching automatically.
In simple terms, the Drupal Entity API acts as a bridge between your code and the database. When you work with a Drupal Entity, you are not interacting with database tables directly. You are using a standardized system that ensures data integrity and proper handling.
The Entity API is built around a few key components:
Entity Type Manager – Responsible for loading and creating entity objects.
Storage Handlers – Manage how entities are stored and retrieved from the database.
Entity Classes – Define the structure and fields of an entity.
When you want to create an entity programmatically, the Entity API provides methods like create() and save() to handle the process safely.
Older methods, such as entity_create(), were commonly used in early Drupal 8 versions, but modern development relies on the Entity API and proper object-oriented practices.
Modern Way to Create Entities Programmatically (Drupal 9/10)
In modern Drupal development, especially in Drupal 9 and 10, the recommended way to create an entity programmatically is by using the Drupal Entity API properly. Instead of relying on older helper functions, developers now use entity classes or the Entity Type Manager service.
The most common approach is to use the entity class's:: create () method. This method prepares a new entity object with the required field values. After setting the values, calling save() stores the entity in the database. This ensures that validation, access checks, and field handling are managed automatically by the system.
For more structured applications, it is better to use the Entity Type Manager service through dependency injection. This avoids static calls and follows Drupal’s modern coding standards. It also makes your code cleaner and easier to test.
Using the proper Drupal Entity methods ensures that when you create an entity programmatically, the system respects field definitions, triggers related hooks, and handles cache invalidation correctly.
Creating Custom Entities in Drupal
While Drupal provides built-in entities like users, nodes, and taxonomy terms, there are many cases where you may need to create custom entity types tailored to your application’s requirements. Custom entities are useful when your data does not fit into standard content types.
In Drupal 8, the system introduced a powerful, structured way to define custom entities using annotations and base classes. Most custom content entities extend ContentEntityBase, while configuration entities extend ConfigEntityBase.
Creating a custom entity involves:
1. Defining an entity annotation that declares the entity ID, label, handlers, and storage.
2. Specifying entity keys such as id, label, and uuid.
3. Defining base fields using BaseFieldDefinition.
4. Configuring routing, permissions, and administrative UI if needed.
The Drupal entity api handles storage, validation, and field management for your custom entity automatically. Once defined, you can drupal create an entity programmatically using the same create() and save() methods used for core entities.
Related: How to Create Custom Entity in Drupal 8 for Content Management
A. How to create a user programmatically.
The fields to be created are as follows:
- Username
- Email address
- Password
- Status
- Roles
- Picture
- Timezone
If you want to create a Drupal user programmatically we can create it the way as given below:
a) This is the first method
The output is shown below:
Related: How to Create Configurable Block programmatically In Drupal 8
The use of Drupal\user\Entity\User; is to include the class User.
User::create()is used to create a user where it takes the details about the user.
Here name is the username whose account is to be created.
Here mail is the email id of the user and pass is the password for the user.
The status tells you if the user account is active or blocked. If it is 1 then the user account is active and if it is 0 then the account is blocked.
The roles mention which roles is given to the user. To give the user more than one role simply pass an array of roles.
The timezone mentions a timezone set for the user.
The user_picture accepts the image’s file id to get the user image. To get the file id we have passed a static image here in $file_image='/var/www/html/drupal/sites/default/files/2017-04/images.jpeg'; The file_get_contents() reads a file into a string. $directory is the name of the folder where you want to save the uploaded image. file_prepare_directory($directory, FILE_CREATE_DIRECTORY); The above line creates the folder if it doesn't exist. The file_save_data saves the files details. The first parameter takes the file content, the second parameter takes the name of the folder you want to save your image and the name of the file, the third parameter tells you to replace the file if it already exists.
b) This is the second way to create user
The first parameter of entity_create accepts the entity type that we want to create and the second parameter accepts an array of values to be used to create that entity. The user created is saved to finally create the user.
Related: How to add Product Programmatically to Drupal Commerce Cart
B. How to create a node programmatically
If you want to create a drupal node programmatically we can create the way as given below:
a) This is the first way to do this:

This will be the output.
Here the use \Drupal\node\Entity\Node; is used to insert the class Node.
Node::create() is used to create a node.
Inside Node::create() the node details is passed.
The type tells you the content type whose node is to be created.
The title is the node title, body is the body part of a node.
The field_mail is the email id to be entered if you have a field for email.
The field_link allows you to add a link if you have any link field and field_date holds the value of date field.
b) This is the second way to create the node
The entity creates function takes two parameters where the first parameter tells you which entity to create and the second parameter should be an array of the node details.
C. How to create a taxonomy term programmatically
If you want to create taxonomy term programmatically we can create the way as given below:
a) This is the first way to create term
The output is shown below:

In above code use Drupal\taxonomy\Entity\Term; is used to insert the class Term
Term::create has been used to create the term where Term is the class name.
Here name and vid are machine names where name represents the name of the new term you want to create, and vid is the name of the taxonomy term whose term you want to create.
b) This is the second way to create a term
The entity create function takes two parameter where the first parameter tells you which entity to create and the second parameter should be an array of the term details.
It should contain the term name and the taxonomy name whose term you want to create. You can add the term description but it’s optional.
D. How to create a custom menu
Create a form inside the Form folder as given in the code below.In Drupal 8 modules we write a form inside a Form folder.
Create a routing file which is module_name.routing.yml Here menu.route is the routing name and _form is the path of the form.
In module_name.links.menu.yml file write the code for the menu as shown below:
links.admin is the name of the menu.
The title will appear as the menu name.
The parent tells you the place where the menu will be created like system.admin will create the menu in the main navigation. If the parent is not mentioned then the menu will be created in the tools.
Related: How to create a custom block programmatically in Drupal 8
The route name is the name of the routing file of whose menu you want to create.
The output is as follows.
![]()
Here TechX is the menu created.
E. How to create a custom permission
Taking the example of the module above, create a file and name it as module_name.permissions.yml
Write the following code into it:
Here 'Menu permission': is the name of the permission that we mention in the routing file ,
The title gives you the name displayed in the drupal's permissions page. In routing file under _permission we mention this permission name. So whichever role has this permission can view the form.
This is how drupal permissions are given to a particular page when you don’t want to show the page for every user or role.
So here we have learnt how to create entities in drupal 8 programmatically. In drupal 8 you can create node, user, taxonomy without code, but sometimes due to various project requirements and we need to create these programmatically.
Related:
How to send mail programmatically in Drupal 8
Best Practices When You Programmatically Create a User in Drupal
When you create a user programmatically, it is important to follow best practices to ensure security, data integrity, and maintainability. While the Drupal Entity API makes user creation straightforward, improper handling can lead to security risks or inconsistent data.
First, always validate the email address before creating a user. Duplicate email accounts can cause authentication and communication issues. Before you programmatically create a user, check whether a user with the same email already exists.
Second, avoid hardcoding passwords in your code. Even though Drupal securely hashes passwords internally, sensitive credentials should never be stored directly in source files. Instead, use secure input handling or generate temporary passwords when needed.
Third, assign roles carefully. When creating a user programmatically, ensure only valid, existing roles are assigned. Avoid automatically granting high-privilege roles such as administrator unless absolutely necessary.
Fourth, always respect access control. Make sure the current user has permission to create accounts. This prevents privilege escalation.
Entity Validation, Access & Security
When working with a Drupal Entity, validation, access control, and security should never be ignored. Even though the Drupal entity api handles many checks automatically, developers must ensure that programmatic operations follow proper standards.
Before saving an entity, always validate the data. Field types, required fields, and allowed values are defined in the entity structure. If invalid data is passed when creating an entity programmatically in Drupal, it may cause errors or inconsistent records. Relying on the Entity API’s built-in validation helps maintain data integrity.
Access control is equally important. Just because you can programmatically create or update an entity does not mean the action should bypass permission checks. Always ensure that the current user has permission to perform the operation. This is especially important when you programmatically create user accounts or assign roles in Drupal.
Security also involves preventing privilege escalation. Avoid assigning high-level roles automatically. Never expose sensitive entity fields through unsecured APIs.