Field Type Catalogue
Every field type Loom understands, with its Go type, MySQL column type, HTML input element, and notes on when to use it.
The full table
type: |
Go | MySQL | HTML | Notes |
|---|---|---|---|---|
text |
string |
VARCHAR(255) |
<input type="text"> |
Short strings; the default |
textarea |
string |
TEXT |
<textarea> |
Multi-line, no formatting |
email |
string |
VARCHAR(255) |
<input type="email"> |
Adds validate:"email" |
phone |
string |
VARCHAR(50) |
<input type="tel"> |
No format validation; user-facing format flexible |
url |
string |
VARCHAR(500) |
<input type="url"> |
Adds validate:"url" |
integer |
int64 |
BIGINT |
<input type="number" step="1"> |
|
decimal |
float64 |
DECIMAL(15,4) |
<input type="number" step="0.01"> |
Money-safe precision |
boolean |
bool |
TINYINT(1) |
<input type="checkbox"> |
|
date |
time.Time |
DATE |
<input type="date"> |
Calendar date, no time |
datetime |
time.Time |
DATETIME |
<input type="datetime-local"> |
|
select |
string |
VARCHAR(100) |
<select> |
Requires options |
radio |
string |
VARCHAR(100) |
radio group | Requires options |
multiselect |
[]string |
JSON |
multi-select | Requires options; stored as JSON array |
link |
*uuid.UUID |
CHAR(36) |
autocomplete | Requires target; FK is documented in SQL but not enforced |
attach |
string |
VARCHAR(500) |
<input type="file"> |
Stores file path / URL |
image |
string |
VARCHAR(500) |
<input type="file"> |
Same as attach, with thumbnail rendering in UI |
json |
map[string]any |
JSON |
JSON editor | Use sparingly — schema-less |
uuid |
uuid.UUID |
CHAR(36) |
<input type="text"> |
Auto-generated; rare (every record already has an id) |
markdown |
string |
LONGTEXT |
markdown editor | Long-form content with formatting |
code |
string |
LONGTEXT |
code editor | Snippets with syntax highlighting |
Required vs optional → Go type adjustment
For non-required fields, the generated Go uses pointer types so nil cleanly represents "no value":
- name: status
type: text # not required
Status *string `db:"status" json:"status"`
For required fields, the type is the bare value:
CompanyName string `db:"company_name" json:"company_name" validate:"required,max=255"`
The exception: types that are already pointer-like (link, multiselect, json) use the same type whether required or not — Loom never emits double-pointers.
Audit columns Loom adds for free
Every Thread's table has these columns automatically. You don't declare them; Loom owns them:
| Column | MySQL | Purpose |
|---|---|---|
id |
CHAR(36) NOT NULL DEFAULT (UUID()) |
Primary key |
created_at |
DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP |
Insertion time |
updated_at |
DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP |
Last-update time |
created_by |
CHAR(36) NOT NULL |
UUID of the user who created the row (from JWT) |
The runtime sets id and created_by on Create. MySQL maintains the timestamp columns. You can read them via the API but you cannot write them.
See also
- Concepts → The Five Field Types Worth Knowing — practical guidance on which to use when
- Reference → Thread YAML Schema — every field option, not just types
← Previous
How to Use Hooks to Normalize Data Before Save
Next →
Adding a Stripe Webhook with Shuttle
Was this article helpful?