Developer Journal

Advanced 2 min read

Creating Custom Entity Types

How to decide on a custom entity and design its storage, forms, permissions, and Views integration.

Last updated August 8, 2026

A custom entity is justified when a domain object needs its own identity, lifecycle, access rules, storage, and query behavior. It is not merely a way to group fields.

Choose content or configuration

Content entities hold operational records and fieldable data. Configuration entities describe deployable site behavior. Pick the model based on lifecycle and ownership, not which annotation example is shorter.

Define handlers deliberately

Entity type metadata wires storage, access, list builders, forms, routes, and Views data. Start with the minimum set, but design keys, indexes, and ownership before production data exists.

Plan updates from day one

Entity schema changes require update paths. Test installation and updates separately, define permissions around operations, and ensure Views queries respect access where required.

First ask why a node is not enough

Nodes already provide fields, revisions, translations, access integration, forms, Views support, and a mature editorial model. A custom content entity is most valuable when the domain object has a lifecycle or semantics that do not fit the node model cleanly. Examples might include operational records, application-specific transactions, or reusable domain objects that should not behave like published content.

Choosing a custom entity means accepting responsibility for more of the surrounding behavior, so the decision should be based on the domain rather than a desire for a custom database table.

Design the entity contract before the UI

Define identifiers, labels, ownership, revisionability, translatability, base fields, storage expectations, and access rules before focusing on administrative forms. Those decisions affect handlers, schema, APIs, and future update paths.

Handlers should be added because the entity needs them. A list builder, access control handler, route provider, Views integration, and form classes are useful pieces, but not every entity requires every optional subsystem on its first release.

Schema evolution is part of the feature

A custom entity rarely remains frozen after production data exists. Adding a field, changing storage expectations, or introducing revisions needs an update path that works on existing databases, not only a clean installation.

Test both installation and upgrade scenarios. The ability to create the entity type on a fresh site proves a different thing from the ability to evolve thousands of existing records safely.

Key Takeaways

  • Create an entity only for a real domain lifecycle.
  • Design access and storage before UI.
  • Provide update paths for schema evolution.

Further Reading