Field Type Matrix vs. the Market

The field catalog is one of the platform's cores: the kind determines the Postgres column, validation, the panel control, the type in OpenAPI/GraphQL, the render variant, and the FLS rule. This document compares our catalog (src/platform/schema/field-types.ts, 56 types + variants in field-variants.ts) with competitor catalogs and points out what is really missing.

Legend: yes = full native support, part. = partial / via another type or variant, plugin = only via an extension, no = missing.

1. Text fields and identifiers

TypeUsStrapi 5ContentfulSanityPayload 3Directus 11HygraphContentstack
text (single line)yesyesyesyesyesyesyesyes
longTextyesyesyesyesyesyesyesyes
richText (structured)yesyesyesyesyesyesyesyes
markdownyespart.part.pluginpart.yesyespart.
html (raw WYSIWYG)nopart.nonopart.yesnoyes
codeyespluginnopluginpluginyesnoplugin
slug / uidyesyesyesyesyespart.yesyes
uuidyespart.nonopart.yesyesno
autoIncrementyespart.nononoyesnono
email / url / phone / ipAddressyespart.part.part.yesyespart.part.
password (hashed, never in API)yesyesnonoyesyesnono
secret (reversible encryption)nononononononono

2. Numbers, time, units

TypeUsStrapi 5ContentfulSanityPayload 3Directus 11HygraphContentstack
integer / decimalyesyesyesyesyesyesyesyes
percent / slider / progress / ratingyespart.nopart.part.part.nono
money (amount + currency)yesnonopluginnopart.nono
measurement (value + unit)yesnonononononono
currency / country / language / timezoneyesnonopluginpart.part.nono
date / dateTime / time / durationyesyesyesyesyesyesyesyes
dateRangeyesnonononononono
numberRangenononononononono
dateTime with timezone stored in the recordpart.nopart.nonoyesnono

3. Choices, taxonomies, relations

TypeUsStrapi 5ContentfulSanityPayload 3Directus 11HygraphContentstack
enumeration (single select)yesyesyesyesyesyesyesyes
multiSelect (checkbox group)yespart.yesyesyesyesyesyes
tags (free + dictionary)yespart.part.yespart.yespart.yes
relation 1-1 / 1-n / n-myesyesyesyesyesyesyesyes
polymorphic relation (many-to-any)nonopart.yesyesyespart.no
tree self-relation (parent/tree)part.part.part.part.part.yesnono
userRefyesyesnonoyesyesnono
lookup (mirrored field from a relation)nononononopart.nono
rollup / aggregate over a relationnononononopart.nono
formula / computednonononopart.nonono
sortOrder (manual drag ordering)nopart.nononoyesnono
remoteSelect (options from an external API)nopluginpluginyesyespart.pluginplugin

4. Media and files

TypeUsStrapi 5ContentfulSanityPayload 3Directus 11HygraphContentstack
file / image / video / audioyesyesyesyesyesyesyesyes
assetGallery (multiple, sortable)yesyesyesyesyesyesyesyes
focal point / crop presetsnopart.yesyesyespart.yespart.
externalAsset (Cloudinary/Drive/DAM ref)part.pluginpluginpluginpluginpart.part.plugin
embed (oEmbed/iframe)yesnonopluginnonoyesno
signatureyesnonononononono
barcode / QRyesnonononononono

5. Complex structures and UI

TypeUsStrapi 5ContentfulSanityPayload 3Directus 11HygraphContentstack
component (reusable)yesyespart.yesyespart.yesyes
dynamicZone / blocksyesyespart.yesyespart.yesyes
list (repeater) / object (group)yesyespart.yesyespart.yesyes
json (arbitrary structure)yesyesyesnoyesyesyesyes
json validated against JSON Schemapart.nonononononono
table / matrix (row grid)nononopluginnononoyes
geolocation (point)yesnoyesyesyesyesnono
geometry (line / polygon)nononopluginnoyesnono
address (structured)yesnonononononono
color / icon / emojiyespart.nopluginnopart.nopart.
presentational fields (divider, notice, button)nonononoyesyesnono
vector / embedding (pgvector, AI search)nopluginnopart.nononono

6. What is actually missing

Ordered by impact on real-world deployments:

  1. Polymorphic relation (many-to-any) — a single field pointing at multiple models.

Blocks typical layouts ("promo block links to either an article or a product"). Requires a discriminator column plus a union in GraphQL (we already have the pattern from dynamicZone).

  1. Derived fields: lookup, rollup, formula — readable, non-writable fields computed

from a relation (e.g. orderTotal, articlesCount). Must pass through FLS as read-only and be computed in the Query Engine, not on the client.

  1. sortOrder — manual drag-and-drop record ordering; today autoIncrement

assigns an order but doesn't let you change it.

  1. Presentational fields (divider, notice, uiButton) — only layout sections exist;

instructional elements with no persistence are missing (Payload UI field, Directus presentation).

  1. numberRange — a numeric range (price bracket, power range) as a single field

with min <= max validation; we only have dateRange.

  1. Focal point + crop presets on image — the market standard for responsive delivery;

today we only return a URL and metadata.

  1. remoteSelect — options fetched from an external API/platform endpoint instead of a

static enumeration (PIM/ERP integrations).

  1. table / matrix — a simple row-column grid for technical specs,

today worked around with list + object.

  1. geometry (linestring/polygon) — delivery areas, routes, zones; geolocation

only covers a point.

  1. html (raw) — a field for external HTML (newsletters, migrated content) with sanitization

at delivery time, distinct from richText.

  1. vector / embedding — a pgvector column auto-populated from text fields,

for semantic search and recommendations ("related articles").

  1. secret (reversible encryption) — password hashes one-way; a field is missing

for integration keys that must be read back on the server side.

  1. json validated against JSON Schema — today json accepts any object;

schema validation would give the same contract in REST and GraphQL.

  1. dateTime with timezone stored in the record — local events need a pair

(instant, IANA tz); today that's two separate fields.

  1. tree self-relation as a field type — we have hierarchy in taxonomy and DAM,

but not as a content model field with cycle validation.

Our advantages over the market (not to be lost while expanding): money, measurement, address, dateRange, signature, barcode, duration, progress, embed, autoIncrement, country/language/timezone/currency, and per-field-type render variants.