What is the difference between creating fields programmatically and by exporting settings? We are developing a custom app with decoupling approach. There are going to be many custom entities with fields. What is your preferred way to create fields programmatically, so we have all information in the code and can build our custom logic on it? So far I have identified three ways how to do it:


using the BaseFieldDefinition::create in the entity class.
using .yaml files in the modules config/install directory
using Features


With the first option, there is a problem that Workflow modules, which would be helpful, does not support the creation of the entity fields in the code (see https://www.drupal.org/project/workflow/issues/2960185). However, we can still replace Workflow module with custom entities and logic.

With other two options I am not entirely sure what are the pros and cons of using them. They just seem to me quite difficult to add custom logic, and/or methods to entities or create new field types (plugins).

Any suggestions will be much appreciated.
For modules common practice is to define base fields with the first option and bundle fields with the second option. Concerning option 3 most use cases of Features are now covered by the configuration management, which you can use to synchronize fields configured in UI to a cloned site. Not only those fields created in UI , but also base fields from option 1 in case they are overridden or bundle fields installed by option 2 if they are modified in UI.