---
title: Field Type Gallery
description: Complete reference for all 48 ObjectStack field types with per-type configuration properties
---

# Field Type Gallery

ObjectStack provides **48 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.

<Callout type="info">
**Source:** `packages/spec/src/data/field.zod.ts`  
**Import:** `import { FieldTypeSchema, FieldSchema } from '@objectstack/spec/data'`
</Callout>

---

## Text Types

### `text`
Single-line plain text input.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `maxLength` | `number` | — | Maximum character length |
| `minLength` | `number` | — | Minimum character length |
| `format` | `string` | — | Validation format pattern |
| `caseSensitive` | `boolean` | `true` | Case-sensitive uniqueness checks |

```typescript
{ name: 'first_name', label: 'First Name', type: 'text', maxLength: 100 }
```

### `textarea`
Multi-line text input for longer content.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `maxLength` | `number` | — | Maximum character length |
| `minLength` | `number` | — | Minimum character length |

```typescript
{ name: 'description', label: 'Description', type: 'textarea', maxLength: 5000 }
```

### `email`
Email address with built-in format validation.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `maxLength` | `number` | — | Maximum character length |

```typescript
{ name: 'email', label: 'Email', type: 'email', required: true, unique: true }
```

### `url`
URL with format validation.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `maxLength` | `number` | — | Maximum character length |

```typescript
{ name: 'website', label: 'Website', type: 'url' }
```

### `phone`
Phone number field.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `maxLength` | `number` | — | Maximum character length |
| `format` | `string` | — | Phone format pattern |

```typescript
{ name: 'phone', label: 'Phone', type: 'phone' }
```

### `password`
Masked password input (stored encrypted).

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

---

## Rich Content Types

### `markdown`
Markdown-formatted text with preview support.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `maxLength` | `number` | — | Maximum character length |

```typescript
{ name: 'readme', label: 'README', type: 'markdown' }
```

### `html`
Rich HTML content.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `maxLength` | `number` | — | Maximum character length |

```typescript
{ name: 'body', label: 'Body', type: 'html' }
```

### `richtext`
WYSIWYG rich text editor content.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `maxLength` | `number` | — | Maximum character length |

```typescript
{ name: 'content', label: 'Content', type: 'richtext' }
```

---

## Number Types

### `number`
Numeric value with optional precision.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `precision` | `number` | — | Total digits |
| `scale` | `number` | — | Decimal places |
| `min` | `number` | — | Minimum value |
| `max` | `number` | — | Maximum value |

```typescript
{ name: 'quantity', label: 'Quantity', type: 'number', min: 0, max: 99999 }
```

### `currency`
Monetary value with currency configuration.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `precision` | `number` | — | Total digits |
| `scale` | `number` | — | Decimal places |
| `min` | `number` | — | Minimum value |
| `max` | `number` | — | Maximum value |
| `currencyConfig.precision` | `number` | `2` | Decimal precision for currency |
| `currencyConfig.currencyMode` | `'dynamic' \| 'fixed'` | `'dynamic'` | Whether currency is per-record or fixed |
| `currencyConfig.defaultCurrency` | `string` | `'CNY'` | Default currency code |

```typescript
{ name: 'price', label: 'Price', type: 'currency', currencyConfig: { precision: 2, currencyMode: 'fixed', defaultCurrency: 'USD' } }
```

### `percent`
Percentage value (0–100 or decimal).

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `precision` | `number` | — | Total digits |
| `scale` | `number` | — | Decimal places |
| `min` | `number` | — | Minimum value |
| `max` | `number` | — | Maximum value |

```typescript
{ name: 'discount', label: 'Discount', type: 'percent', min: 0, max: 100 }
```

---

## Date & Time Types

### `date`
Date value (no time component).

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

### `datetime`
Date and time value with timezone support.

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

### `time`
Time-only value (no date component).

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

---

## Boolean Types

### `boolean`
Standard true/false field.

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

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

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

---

## Selection Types

### `select`
Single-choice dropdown.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `options` | `SelectOption[]` | **required** | List of available options |

**SelectOption properties:**

| Property | Type | Required | Description |
|:---|:---|:---|:---|
| `label` | `string` | ✅ | Display label |
| `value` | `string` | ✅ | Machine value (snake_case) |
| `color` | `string` | — | Badge color |
| `default` | `boolean` | — | Pre-selected option |

```typescript
{
  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`.

```typescript
{
  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`.

```typescript
{
  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`.

```typescript
{
  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).

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `reference` | `string` | **required** | Target object name (snake_case) |
| `referenceFilters` | `object` | — | Filters to restrict available options |
| `deleteBehavior` | `'restrict' \| 'cascade' \| 'set_null'` | `'restrict'` | Behavior when referenced record is deleted |

```typescript
{ name: 'assigned_to', label: 'Assigned To', type: 'lookup', reference: 'user' }
```

### `master_detail`
Parent-child relationship (cascading delete by default).

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `reference` | `string` | **required** | Target (master) object name |
| `referenceFilters` | `object` | — | Filters to restrict available options |
| `writeRequiresMasterRead` | `boolean` | — | Require read access on master to write detail |
| `deleteBehavior` | `'restrict' \| 'cascade' \| 'set_null'` | `'cascade'` | Behavior when parent is deleted |
| `inlineEdit` | `boolean` | `false` | Render child records inline on the parent create/edit form |
| `inlineColumns` | `array` | — | Optional explicit inline grid columns |
| `inlineAmountField` | `string` | — | Numeric child field used for the inline running total |

```typescript
{
  name: 'order',
  label: 'Order',
  type: 'master_detail',
  reference: 'order',
  inlineEdit: true,
  inlineAmountField: 'line_total',
}
```

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

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `reference` | `string` | **required** | Same object (self-reference) |

```typescript
{ name: 'parent_category', label: 'Parent Category', type: 'tree', reference: 'category' }
```

---

## Media Types

All media types support the `fileAttachmentConfig` property:

| Property | Type | Description |
|:---|:---|:---|
| `maxSize` | `number` | Maximum file size in bytes |
| `minSize` | `number` | Minimum file size in bytes |
| `allowedTypes` | `string[]` | Allowed file extensions |
| `blockedTypes` | `string[]` | Blocked file extensions |
| `allowedMimeTypes` | `string[]` | Allowed MIME types |
| `blockedMimeTypes` | `string[]` | Blocked MIME types |
| `virusScan` | `boolean` | Enable virus scanning |
| `storageProvider` | `string` | Storage provider name |
| `storageBucket` | `string` | Storage bucket name |
| `allowMultiple` | `boolean` | Allow multiple files |
| `versioningEnabled` | `boolean` | Enable file versioning |
| `maxVersions` | `number` | Maximum version count |
| `publicRead` | `boolean` | Publicly accessible |
| `presignedUrlExpiry` | `number` | URL expiry in seconds |

### `image`
Image file with optional validation.

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

### `file`
Generic file attachment.

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

### `avatar`
Profile image (typically square, small).

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

### `video`
Video file attachment.

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

### `audio`
Audio file attachment.

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

---

## Computed Types

### `formula`
Calculated field using an expression.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `expression` | `string` | **required** | Calculation expression |
| `cached` | `object` | — | Cache settings for computed result |

```typescript
{ name: 'total', label: 'Total', type: 'formula', expression: 'quantity * unit_price' }
```

### `summary`
Roll-up summary from child records.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `summaryOperations.object` | `string` | **required** | Child object to aggregate |
| `summaryOperations.field` | `string` | **required** | Child field to aggregate; ignored for `count` |
| `summaryOperations.function` | `enum` | **required** | `count`, `sum`, `avg`, `min`, or `max` |
| `summaryOperations.relationshipField` | `string` | auto | Child FK back to the parent when it cannot be inferred |

```typescript
{
  name: 'task_count',
  label: 'Task Count',
  type: 'summary',
  summaryOperations: {
    object: 'task',
    field: 'id',
    function: 'count',
    relationshipField: 'project',
  },
}
```

### `autonumber`
Auto-incrementing number with format template.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `autonumberFormat` | `string` | — | Format template (e.g., `'INV-{0000}'`) |

```typescript
{ name: 'ticket_number', label: 'Ticket #', type: 'autonumber', autonumberFormat: 'TKT-{0000}' }
```

---

## Enhanced Types

### `location`
Geographic coordinates with optional map display.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `displayMap` | `boolean` | — | Show interactive map |
| `allowGeocoding` | `boolean` | — | Enable address-to-coordinates conversion |

```typescript
{ name: 'headquarters', label: 'Location', type: 'location', displayMap: true, allowGeocoding: true }
```

### `address`
Structured postal address.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `addressFormat` | `string` | — | Country-specific address format |

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

### `code`
Source code with syntax highlighting.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `language` | `string` | — | Programming language for highlighting |
| `theme` | `string` | — | Editor theme |
| `lineNumbers` | `boolean` | — | Show line numbers |

```typescript
{ name: 'snippet', label: 'Code Snippet', type: 'code', language: 'typescript', lineNumbers: true }
```

### `json`
Raw JSON data.

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

### `color`
Color picker with format options.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `colorFormat` | `string` | — | Color format (`hex`, `rgb`, `hsl`) |
| `allowAlpha` | `boolean` | — | Allow alpha transparency |
| `presetColors` | `string[]` | — | Preset color palette |

```typescript
{ name: 'brand_color', label: 'Brand Color', type: 'color', colorFormat: 'hex', presetColors: ['#FF0000', '#00FF00', '#0000FF'] }
```

### `rating`
Star rating input.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `maxRating` | `number` | `5` | Maximum rating value |
| `allowHalf` | `boolean` | `false` | Allow half-star ratings |

```typescript
{ name: 'satisfaction', label: 'Rating', type: 'rating', maxRating: 5, allowHalf: true }
```

### `slider`
Range slider input.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `min` | `number` | — | Minimum value |
| `max` | `number` | — | Maximum value |
| `step` | `number` | — | Step increment |
| `showValue` | `boolean` | — | Display current value |
| `marks` | `object` | — | Tick marks on slider |

```typescript
{ name: 'confidence', label: 'Confidence', type: 'slider', min: 0, max: 100, step: 5, showValue: true }
```

### `signature`
Digital signature capture.

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

### `qrcode`
QR/barcode generator and scanner.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `barcodeFormat` | `string` | — | Barcode format type |
| `qrErrorCorrection` | `string` | — | QR error correction level |
| `displayValue` | `boolean` | — | Display decoded value |
| `allowScanning` | `boolean` | — | Enable camera scanning |

```typescript
{ name: 'asset_tag', label: 'Asset Tag', type: 'qrcode', allowScanning: true }
```

### `progress`
Progress bar (0–100).

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

### `tags`
Tag input with autocomplete.

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

---

## AI / ML Types

### `vector`
Vector embeddings for semantic search and similarity.

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `vectorConfig.dimensions` | `number` | **required** | Vector dimensionality (e.g., 1536 for OpenAI) |
| `vectorConfig.distanceMetric` | `'cosine' \| 'euclidean' \| 'dotProduct' \| 'manhattan'` | `'cosine'` | Distance calculation method |
| `vectorConfig.normalized` | `boolean` | `false` | Whether vectors are pre-normalized |
| `vectorConfig.indexed` | `boolean` | `true` | Enable vector indexing |
| `vectorConfig.indexType` | `'hnsw' \| 'ivfflat' \| 'flat'` | — | Index algorithm |

```typescript
{
  name: 'embedding', label: 'Embedding', type: 'vector',
  vectorConfig: { dimensions: 1536, distanceMetric: 'cosine', indexed: true, indexType: 'hnsw' }
}
```

---

## Universal Field Properties

These properties are available on **all** field types:

| Property | Type | Default | Description |
|:---|:---|:---|:---|
| `name` | `string` | **required** | Machine name (snake_case) |
| `label` | `string` | — | Human-readable display label |
| `description` | `string` | — | Field description / help text |
| `type` | `FieldType` | **required** | One of the 48 field types |
| `required` | `boolean` | `false` | Whether the field is required |
| `unique` | `boolean` | `false` | Enforce uniqueness |
| `multiple` | `boolean` | `false` | Allow array of values |
| `searchable` | `boolean` | `false` | Include in search index |
| `sortable` | `boolean` | — | Allow sorting by this field |
| `hidden` | `boolean` | `false` | Hide from default views |
| `readonly` | `boolean` | `false` | Prevent user edits |
| `index` | `boolean` | `false` | Create database index |
| `externalId` | `boolean` | `false` | External system identifier |
| `defaultValue` | `any` | — | Default value for new records |
| `group` | `string` | — | Field grouping / section |
| `inlineHelpText` | `string` | — | Inline help tooltip |
| `trackFeedHistory` | `boolean` | — | Track changes in activity feed |
| `encryptionConfig` | `object` | — | Field-level encryption settings |
| `maskingRule` | `object` | — | Data masking configuration |
| `dependencies` | `object` | — | Dependent field configuration |
| `dataQuality` | `object` | — | Data quality validation rules |
| `visibleWhen` | `Expression` | — | Show field only when predicate is true |
| `readonlyWhen` | `Expression` | — | Make field read-only when predicate is true |
| `requiredWhen` | `Expression` | — | Require field when predicate is true |
| `conditionalRequired` | `Expression` | — | Deprecated alias of `requiredWhen` |

---

## Field Type Decision Tree

Use this guide to choose the right field type:

```
Is it text?
├── Short text (< 255 chars) → text
├── Long text → textarea
├── Formatted text → markdown | html | richtext
├── Email address → email
├── URL → url
├── Phone number → phone
├── Secret value → password
└── Source code → code

Is it a number?
├── Integer or decimal → number
├── Money amount → currency
└── Percentage → percent

Is it a date/time?
├── Date only → date
├── Date + time → datetime
└── Time only → time

Is it a choice?
├── Single choice (dropdown) → select
├── Single choice (visible) → radio
├── Multiple choices (dropdown) → multiselect
└── Multiple choices (visible) → checkboxes

Is it a reference?
├── Simple foreign key → lookup
├── Parent-child (cascade delete) → master_detail
└── Self-referential hierarchy → tree

Is it a file?
├── Any file → file
├── Image → image
├── Profile picture → avatar
├── Video → video
└── Audio → audio

Is it computed?
├── Formula calculation → formula
├── Roll-up summary → summary
└── Auto-incrementing ID → autonumber

Is it specialized?
├── Geographic location → location
├── Postal address → address
├── Yes/No toggle → boolean | toggle
├── Star rating → rating
├── Range slider → slider
├── Color picker → color
├── Raw JSON → json
├── Tags/Labels → tags
├── Progress bar → progress
├── Signature → signature
├── QR/Barcode → qrcode
└── AI embedding → vector
```
