Skip to content


Metadata is intended for: storing system data such as entity's fields and relationships, specifying frontend controllers, views, panels, defining fields, dashlets, and other data needed for the application.


  • aclDefs – access control for scopes and entity types
  • selectDefs – filters for entity types
  • recordDefs – CRUD-specific parameters for entity types
  • clientDefs – front-end parameters entity types
  • scopes – general parmeters for scopes and entity types
  • entityAcl – access restriction for specific fields and links for entity types
  • entityDefs – entity definitions (fields, links, indexes etc.)
  • fields – field types definitions
  • app – application definitions

How to access


The Metadata instance (of Espo\Core\Utils\Metadata class) is available in DI Container.

Path to a needed parameter is specified with an array.

// entityDefs > Account > fields > type
$value = $metadata->get(['entityDefs', 'Account', 'fields', 'name', 'type']);

will return the string value "varchar".

$metadata->get(['entityDefs', 'Account', 'fields']);

will return an associative array with definitions of all fields.


Metadata object is accessible from all view objects by method #getMetadata. It works the same way as backend's one.

this.getMetadata().get(['entityDefs', 'Account', 'fields', 'name', 'type']);

How it's stored

Metadata is stored in JSON files that can be located in different places:

  • application/Espo/Resources/metadata/
  • application/Espo/Modules/{MODULE_NAME}/Resources/metadata/
  • custom/Espo/Modules/{MODULE_NAME}/Resources/metadata/
  • custom/Espo/Custom/Resources/metadata/

When you access data by path clientDefs.Account.views.edit the first lexeme clientDefs corresponds to dir name, the second Account to file name Account.json. All following lexemes correspond to path in the JSON.

    "views": {
        "edit": "crm:views/account/views/edit" 

All JSON files from these directories get merged recursively into a single file and stored in a cache file.


Since metadata is merged recursively you can easily redefine JSON objects and arrays in the custom directory.

You can append values to existing arrays by using "__APPEND__" string as the first element of array.


    "fields": {
        "employeeCount": {
          "type": "int"
        "type": {
            "options": [