Fields and field types
A field is one value a record carries. Fields come from two places: the ones a module ships with a kind, and the ones you add yourself. They behave the same on a record, but they differ in where their definition lives.
Native fields
A module declares a kind's built-in fields in its manifest. A native field has a
name, a type, and sometimes a role that tells the platform what the field
means. Native field types are text, number, boolean, date, image-path,
url, and object (a free-form JSON blob the kernel treats as opaque and
renderers show as keys).
Custom fields
You add a custom field to any kind whenever you want to track something the module did not ship. A custom field's definition is stored per workspace, its value is stored on the record, and its type is one of:
| Type | For |
|---|---|
text | names, notes, and free text |
number | counts, measurements, prices |
boolean | a yes / no flag |
date | a calendar date |
url | a link |
richtext | formatted long-form text |
computed | a read-only value from a template (see below) |
relation | a link to another record |
member | a person in the workspace |
A member field stores a user id and renders their display name, resolved at
read time so a rename propagates rather than leaving a stale snapshot. It is the
type the assignee role sits on.
A text field can carry a list of choices, which turns it into a dropdown, so
a status or category picks from a fixed set. A choice value can carry a free-text
note alongside it, stored under the field's name with a _note suffix, so the
value stays groupable while the detail is kept. A number field can carry a unit
(mm, g, in). The unit is free text that the units vocabulary resolves at
render time, and it is what size-aware features read rather than the field's name.
A computed field holds a template instead of a stored value, and it has its own page,
Computed fields. Linking a record to
another record is a relation field, covered under
Relationships.
Renderers
A custom field can name a renderer that controls how its value is drawn on detail
pages and list rows. The built-in renderers are text, color-hex, image-url,
url-link, year, boolean, code, markdown, and qr. A field with no
renderer draws as plain text.
Field roles
A role gives a field a job the platform can key off, independent of what the field is called. The roles are:
| Role | Meaning |
|---|---|
title | the record's display name |
subtitle | a secondary line under the title |
image | the record's picture |
summary | a short description |
quantity | the count this record is measured in |
unit | the unit that quantity is counted in |
Roles are why an action written for "anything with a quantity" works across
modules: the action matches on the quantity role, so it applies to a part, a
consumable, or any kind that declared a quantity field, no matter the field's
name. Actions declare which kinds they apply to using kinds, roles, or
traits. See
wires for where that matters.
What a field means
A record role is a second, independent axis from the presentation role above.
Presentation roles say how to draw a field, and a record role says what the field
is, so a consumer can target it without ever matching an English name. That is
the rule the whole thing exists to enforce: a mapper looking for a field literally
called acquired_from works in exactly the workspace that inspired it and
silently does nothing in every other.
| Record role | The field holds |
|---|---|
category | what kind of thing this record is, within its table |
pack | the packaging count of the physical item (a single, a 10-pack) |
identifier | a value physically marked on the object, like a serial or asset tag |
expiry | when it goes off or runs out |
assignee | who it is assigned to |
acquired-from | where you got it |
acquired-on | when you got it |
acquired-for | what it cost you |
seller | who sold it, kept alongside the shop rather than replacing it |
Bundles declare these, and you can set one on a custom field yourself. There may
be more than one identifier on a kind, but category and pack are at most one
each.
category and pack are distinct from quantity and unit, which are the
presentation roles above: quantity is how many you have, unit is what they are
counted in, and pack is how many base units are in the package you are holding.
Three different counting dimensions.
Relabelling without migrating
You can rename, hide, or reorder a kind's native fields for your workspace without
changing what is stored. The value stays under its original name, and only the label
and its place in the form change. So "call the sku field Part number" is a
presentation change resolved at load time, not a data migration.