ObjectStackObjectStack

Field Type Gallery

Complete reference for every ObjectStack field type with per-type configuration properties

Field Type Gallery

ObjectStack provides a comprehensive set of field types covering every data modeling need — from basic text and numbers to AI vectors and rich media. This guide organizes them by category with per-type configuration details.

Source: packages/spec/src/data/field.zod.ts
Import: import { FieldType, FieldSchema } from '@objectstack/spec/data'


Text Types

text

Single-line plain text input.

PropertyTypeDefaultDescription
maxLengthnumberMaximum character length
minLengthnumberMinimum character length
formatstringValidation format pattern
{ name: 'first_name', label: 'First Name', type: 'text', maxLength: 100 }

textarea

Multi-line text input for longer content.

PropertyTypeDefaultDescription
maxLengthnumberMaximum character length
minLengthnumberMinimum character length
{ name: 'description', label: 'Description', type: 'textarea', maxLength: 5000 }

email

Email address with built-in format validation.

PropertyTypeDefaultDescription
maxLengthnumberMaximum character length
{ name: 'email', label: 'Email', type: 'email', required: true, unique: true }

url

URL with format validation.

PropertyTypeDefaultDescription
maxLengthnumberMaximum character length
{ name: 'website', label: 'Website', type: 'url' }

phone

Phone number field.

PropertyTypeDefaultDescription
maxLengthnumberMaximum character length
formatstringPhone format pattern
{ name: 'phone', label: 'Phone', type: 'phone' }

password

Masked password input (stored as a one-way hash, owned by the auth subsystem). For reversible encrypted-at-rest secrets (API keys, tokens), use the secret type instead.

{ name: 'password', label: 'Password', type: 'password', required: true }

secret

Reversible, encrypted-at-rest value (DB password, API key, token). Unlike password (a one-way hash), a secret is encrypted on write via the registered crypto provider, stored as an opaque ref on the row, and masked on read. Fail-closed: with no provider configured, writes throw rather than persist cleartext.

{ name: 'api_key', label: 'API Key', type: 'secret' }

Rich Content Types

markdown

Markdown-formatted text with preview support.

PropertyTypeDefaultDescription
maxLengthnumberMaximum character length
{ name: 'readme', label: 'README', type: 'markdown' }

html

Rich HTML content.

PropertyTypeDefaultDescription
maxLengthnumberMaximum character length
{ name: 'body', label: 'Body', type: 'html' }

richtext

WYSIWYG rich text editor content.

PropertyTypeDefaultDescription
maxLengthnumberMaximum character length
{ name: 'content', label: 'Content', type: 'richtext' }

Number Types

number

Numeric value with optional precision.

PropertyTypeDefaultDescription
precisionnumberTotal digits
scalenumberDecimal places
minnumberMinimum value
maxnumberMaximum value
{ name: 'quantity', label: 'Quantity', type: 'number', min: 0, max: 99999 }

currency

Monetary value with currency configuration.

PropertyTypeDefaultDescription
precisionnumberTotal digits
scalenumberDecimal places
minnumberMinimum value
maxnumberMaximum value
currencyConfig.precisionnumber2Decimal precision for currency
currencyConfig.currencyMode'dynamic' | 'fixed''dynamic'Whether currency is per-record or fixed
currencyConfig.defaultCurrencystring'CNY'Default currency code
{ name: 'price', label: 'Price', type: 'currency', currencyConfig: { precision: 2, currencyMode: 'fixed', defaultCurrency: 'USD' } }

percent

Percentage value (0–100 or decimal).

PropertyTypeDefaultDescription
precisionnumberTotal digits
scalenumberDecimal places
minnumberMinimum value
maxnumberMaximum value
{ name: 'discount', label: 'Discount', type: 'percent', min: 0, max: 100 }

Date & Time Types

date

Date value (no time component).

{ name: 'birth_date', label: 'Birth Date', type: 'date' }

datetime

Date and time value with timezone support.

{ name: 'created_at', label: 'Created At', type: 'datetime', readonly: true }

time

Time-only value (no date component).

{ name: 'start_time', label: 'Start Time', type: 'time' }

Boolean Types

boolean

Standard true/false field.

{ name: 'is_active', label: 'Active', type: 'boolean', defaultValue: true }

toggle

Toggle switch (functionally identical to boolean, different UI).

{ name: 'notifications_enabled', label: 'Notifications', type: 'toggle' }

Selection Types

select

Single-choice dropdown.

PropertyTypeDefaultDescription
optionsSelectOption[]requiredList of available options

SelectOption properties:

PropertyTypeRequiredDescription
labelstringDisplay label
valuestringMachine value (snake_case)
colorstringBadge color
defaultbooleanPre-selected option
{
  name: 'status', label: 'Status', type: 'select',
  options: [
    { label: 'Open', value: 'open', color: 'blue', default: true },
    { label: 'In Progress', value: 'in_progress', color: 'yellow' },
    { label: 'Done', value: 'done', color: 'green' }
  ]
}

multiselect

Multi-choice dropdown. Same options property as select.

{
  name: 'tags', label: 'Tags', type: 'multiselect',
  options: [
    { label: 'Bug', value: 'bug' },
    { label: 'Feature', value: 'feature' },
    { label: 'Enhancement', value: 'enhancement' }
  ]
}

radio

Radio button group (single choice). Same options property as select.

{
  name: 'priority', label: 'Priority', type: 'radio',
  options: [
    { label: 'Low', value: 'low' },
    { label: 'Medium', value: 'medium', default: true },
    { label: 'High', value: 'high' }
  ]
}

checkboxes

Checkbox group (multi-choice). Same options property as select.

{
  name: 'features', label: 'Features', type: 'checkboxes',
  options: [
    { label: 'Email', value: 'email' },
    { label: 'SMS', value: 'sms' },
    { label: 'Push', value: 'push' }
  ]
}

Relational Types

lookup

Reference to a record in another object (foreign key).

PropertyTypeDefaultDescription
referencestringrequiredTarget object name (snake_case)
referenceFiltersstring[]Legacy — accepted by the schema but not read by the record-picker (filters nothing). Use structured lookupFilters + dependsOn instead; see Relationships
deleteBehavior'restrict' | 'cascade' | 'set_null''set_null'Behavior when referenced record is deleted (a required lookup left at the default set_null is escalated to restrict, since a NOT NULL foreign key cannot be cleared)
{ name: 'company', label: 'Company', type: 'lookup', reference: 'account' }

user

Person picker — a lookup specialized to the built-in sys_user object. Stored identically to lookup (foreign key to sys_user.id; multiple: true stores an array) and resolved through the same $expand machinery. Supports defaultValue: 'current_user' to stamp the acting user's id on insert.

Field.user({ label: 'Assignee' })
Field.user({ label: 'Watchers', multiple: true })
Field.user({ label: 'Owner', defaultValue: 'current_user' })

master_detail

Parent-child relationship (cascading delete by default).

PropertyTypeDefaultDescription
referencestringrequiredTarget (master) object name
referenceFiltersstring[]Legacy — accepted by the schema but not read by the record-picker (filters nothing). Use structured lookupFilters + dependsOn instead; see Relationships
deleteBehavior'restrict' | 'cascade' | 'set_null''cascade'Behavior when parent is deleted (master-detail cascades unless set to restrict)
inlineEditboolean | 'grid' | 'form'Edit child records inline on the parent create/edit form (true = auto-pick, 'grid', or 'form')
inlineColumnsarrayOptional explicit inline grid columns
inlineAmountFieldstringNumeric child field used for the inline running total
{
  name: 'order',
  label: 'Order',
  type: 'master_detail',
  reference: 'order',
  inlineEdit: true,
  inlineAmountField: 'line_total',
}

tree

Self-referential hierarchy (e.g., categories, org chart).

PropertyTypeDefaultDescription
referencestringrequiredSame object (self-reference)
{ name: 'parent_category', label: 'Parent Category', type: 'tree', reference: 'category' }

Media Types

All media types support the fileAttachmentConfig property:

PropertyTypeDescription
maxSizenumberMaximum file size in bytes
minSizenumberMinimum file size in bytes
allowedTypesstring[]Allowed file extensions
blockedTypesstring[]Blocked file extensions
allowedMimeTypesstring[]Allowed MIME types
blockedMimeTypesstring[]Blocked MIME types
virusScanbooleanEnable virus scanning
storageProviderstringStorage provider name
storageBucketstringStorage bucket name
allowMultiplebooleanAllow multiple files
versioningEnabledbooleanEnable file versioning
maxVersionsnumberMaximum version count
publicReadbooleanPublicly accessible
presignedUrlExpirynumberURL expiry in seconds

image

Image file with optional validation.

{
  name: 'photo', label: 'Photo', type: 'image',
  fileAttachmentConfig: { maxSize: 5242880, allowedMimeTypes: ['image/png', 'image/jpeg'] }
}

file

Generic file attachment.

{
  name: 'attachment', label: 'Attachment', type: 'file',
  fileAttachmentConfig: { maxSize: 10485760, virusScan: true }
}

avatar

Profile image (typically square, small).

{ name: 'avatar', label: 'Avatar', type: 'avatar' }

video

Video file attachment.

{
  name: 'demo_video', label: 'Demo Video', type: 'video',
  fileAttachmentConfig: { maxSize: 104857600, allowedMimeTypes: ['video/mp4'] }
}

audio

Audio file attachment.

{
  name: 'recording', label: 'Recording', type: 'audio',
  fileAttachmentConfig: { maxSize: 52428800 }
}

Computed Types

formula

Calculated field using a CEL expression (see Expressions).

PropertyTypeDefaultDescription
expressionstring | ExpressionrequiredCEL calculation expression
returnType'number' | 'text' | 'boolean' | 'date'Declared value type of the computed result
dependenciesstring[]Fields the formula depends on
{ name: 'total', label: 'Total', type: 'formula', expression: 'record.quantity * record.unit_price', returnType: 'number' }

summary

Roll-up summary from child records.

PropertyTypeDefaultDescription
summaryOperations.objectstringrequiredChild object to aggregate
summaryOperations.fieldstringrequiredChild field to aggregate; ignored for count
summaryOperations.functionenumrequiredcount, sum, avg, min, or max
summaryOperations.relationshipFieldstringautoChild FK back to the parent when it cannot be inferred
{
  name: 'task_count',
  label: 'Task Count',
  type: 'summary',
  summaryOperations: {
    object: 'task',
    field: 'id',
    function: 'count',
    relationshipField: 'project',
  },
}

autonumber

Auto-incrementing number with format template.

PropertyTypeDefaultDescription
autonumberFormatstringFormat template (e.g., 'INV-{0000}')
{ name: 'ticket_number', label: 'Ticket #', type: 'autonumber', autonumberFormat: 'TKT-{0000}' }

Embedded Structured Types

These types store structured values as JSON on the parent row — no separate table or foreign key.

composite

Single embedded sub-object with declared sub-fields (similar to a Strapi component / ACF group).

{ name: 'dimensions', label: 'Dimensions', type: 'composite' }

repeater

Repeating embedded sub-object array with declared sub-fields (similar to a Strapi repeatable component / ACF repeater).

{ name: 'line_items', label: 'Line Items', type: 'repeater' }

record

Name-keyed map of embedded sub-objects (Record<string, SubObject>). Insertion order is display order. Used for collections where each item has a stable machine name. See ADR-0007.

{ name: 'settings', label: 'Settings', type: 'record' }

Enhanced Types

location

Geographic coordinates. Stored as { latitude, longitude, altitude?, accuracy? } (latitude −90..90, longitude −180..180). No per-type config properties.

{ name: 'headquarters', label: 'Location', type: 'location' }

address

Structured postal address. Stored as { street, city, state, postalCode, country, countryCode, formatted } (all parts optional). No per-type config properties.

{ name: 'billing_address', label: 'Billing Address', type: 'address' }

code

Source code with syntax highlighting.

PropertyTypeDefaultDescription
languagestringProgramming language for highlighting
{ name: 'snippet', label: 'Code Snippet', type: 'code', language: 'typescript' }

json

Raw JSON data.

{ name: 'metadata', label: 'Metadata', type: 'json' }

color

Color picker. Stores the color value as a string. No per-type config properties.

{ name: 'brand_color', label: 'Brand Color', type: 'color' }

rating

Star rating input.

PropertyTypeDefaultDescription
maxnumber5Maximum rating value (set by the Field.rating(max) factory)
{ name: 'satisfaction', label: 'Rating', type: 'rating', max: 5 }
// or with the factory:
// satisfaction: Field.rating(5, { label: 'Rating' })

slider

Range slider input.

PropertyTypeDefaultDescription
minnumberMinimum value
maxnumberMaximum value
stepnumber1Step increment
{ name: 'confidence', label: 'Confidence', type: 'slider', min: 0, max: 100, step: 5 }

signature

Digital signature capture.

{ name: 'approval_signature', label: 'Signature', type: 'signature' }

qrcode

QR/barcode value rendered as a scannable code. No per-type config properties.

{ name: 'asset_tag', label: 'Asset Tag', type: 'qrcode' }

progress

Progress bar (0–100).

{ name: 'completion', label: 'Completion', type: 'progress' }

tags

Tag input with autocomplete.

{ name: 'labels', label: 'Labels', type: 'tags' }

AI / ML Types

vector

Vector embeddings for semantic search and similarity.

PropertyTypeDefaultDescription
dimensionsnumberrequiredVector dimensionality (e.g., 1536 for OpenAI embeddings)

The nested vectorConfig object (with distanceMetric, indexed, indexType, …) is retained for back-compat only and is a runtime no-op — set the flat dimensions property instead.

{ name: 'embedding', label: 'Embedding', type: 'vector', dimensions: 1536 }
// or with the factory:
// embedding: Field.vector(1536, { label: 'Embedding' })

Universal Field Properties

These properties are available on all field types:

PropertyTypeDefaultDescription
namestringrequiredMachine name (snake_case)
labelstringHuman-readable display label
descriptionstringField description / help text
typeFieldTyperequiredOne of the supported field types
requiredbooleanfalseWhether the field is required
uniquebooleanfalseEnforce uniqueness
multiplebooleanfalseAllow array of values
searchablebooleanfalseInclude in search index
sortablebooleantrueAllow sorting by this field
hiddenbooleanfalseHide from default views
readonlybooleanfalsePrevent user edits
indexbooleanfalseCreate database index
externalIdbooleanfalseExternal system identifier
defaultValueanyDefault value for new records
groupstringField grouping / section
inlineHelpTextstringInline help tooltip
trackHistorybooleanRender this field's value changes as entries on the record activity timeline
requiredPermissionsstring[]Capabilities required to read/edit this field (masked on read, denied on write)
dependenciesstring[]Names of fields this field depends on (formulas, visibility rules, etc.)
visibleWhenExpressionShow field only when predicate is true
readonlyWhenExpressionMake field read-only when predicate is true
requiredWhenExpressionRequire field when predicate is true
conditionalRequiredExpressionDeprecated alias of requiredWhen

Choosing a Field Type

Not sure which type fits your data? Follow the Field Type Decision Tree — a flowchart, quick-reference tables, and a use-case mapping for every type in this gallery.

On this page