Struct Tags Complete Reference
Complete reference for struct tags used in TinySystems component schemas.
Source of truth: pkg/schema/json.go in the SDK (custom TinySystems properties) and the swaggest/jsonschema-go reflector (standard JSON Schema tags).
Overview
Struct tags control how Go structs are converted to JSON Schema and rendered in the UI. Go struct tags are single-line — a tag split across lines does not parse.
type Example struct {
Field string `json:"field" required:"true" title:"Field Name" description:"Help text"`
}
Tag values are strings; the schema generator converts "true"/"false" to booleans and numeric strings to numbers where appropriate.
JSON Tags
json
Maps Go field to JSON property name.
Syntax: json:"name" or json:"name,omitempty"
UserName string `json:"userName"` // camelCase
Data string `json:"data,omitempty"` // omit if empty
Ignored string `json:"-"` // exclude from schema
Required for all exported fields.
Standard JSON Schema Tags
These are handled by the jsonschema-go reflector.
required
Syntax: required:"true"
Email string `json:"email" required:"true"`
Field must be provided; the UI shows a required indicator.
minimum / maximum
Numeric range constraints.
Age int `json:"age" minimum:"0" maximum:"150"`
Port int `json:"port" minimum:"1" maximum:"65535"`
minLength / maxLength
String length constraints.
Username string `json:"username" minLength:"3" maxLength:"50"`
minItems / maxItems
Array size constraints.
Tags []string `json:"tags" minItems:"1" maxItems:"10"`
pattern
Regex constraint.
Slug string `json:"slug" pattern:"^[a-z0-9-]+$"`
enum
Restricts to specific values (comma-separated).
Status string `json:"status" enum:"pending,active,completed"`
title
Display label.
UserID string `json:"userId" title:"User ID"`
description
Help text / tooltip.
Timeout string `json:"timeout" description:"Duration to wait before timing out (e.g., 30s, 1m)"`
default
Default value (string; converted to the field's type).
Timeout string `json:"timeout" default:"30s"`
MaxRetries int `json:"maxRetries" default:"3"`
Enabled bool `json:"enabled" default:"true"`
Live values set on the Configuration instance in Ports() are also materialized into the schema as defaults.
TinySystems Custom Tags
The schema generator copies exactly these custom properties from struct tags into the schema (scalarCustomProps in pkg/schema/json.go):
requiredWhen, propertyOrder, optionalWhen, colSpan, tab, align, configurable, shared, $ref, type, readonly, format, language
plus one array-valued property (arrayCustomProps):
enumTitles
Tags not in this list (e.g. widget, hidden) are not supported and are silently dropped.
configurable
Marks the field as data-mappable: its value can be set per-edge in the flow editor (expressions, upstream data). The generator creates a $defs definition for every configurable field.
Data any `json:"data" configurable:"true" title:"Data"`
shared
Makes the field's definition shareable so other nodes can reference it ($ref). On array fields, shared propagates to the items definition.
Context Context `json:"context" shared:"true"`
readonly
Display-only field in the UI.
Status string `json:"status" readonly:"true" title:"Status"`
format
Special rendering format. Values with dedicated renderers in the editor:
| Format | Applies to | Description |
|---|---|---|
textarea | string | Multi-line text input |
code | string | Code editor (pair with language) |
json | string | Code editor in JSON mode |
date-time | string | Date and time picker |
radiobox | string/number + enum | Radio group instead of dropdown |
base64 | string | File upload stored base64-encoded |
select | string/number + enum | Dropdown (default when enum present) |
checkbox | bool | Checkbox |
button | bool | Clickable button (control ports) |
Bio string `json:"bio" format:"textarea"`
Config string `json:"config" format:"code" language:"yaml"`
Start bool `json:"start" format:"button" title:"Start"`
File string `json:"file" format:"base64" title:"Upload"`
Other JSON-Schema format values (e.g. email, uri) are kept in the schema but render as plain text inputs.
language
Code-editor language for format:"code".
Script string `json:"script" format:"code" language:"javascript"`
tab
Groups fields into tabs.
type Settings struct {
Name string `json:"name" tab:"Basic" title:"Name"`
Timeout string `json:"timeout" tab:"Advanced" title:"Timeout"`
Debug bool `json:"debug" tab:"Advanced" title:"Debug Mode"`
}
colSpan
Column width in the 12-column grid layout.
Syntax: colSpan:"col-span-N" where N is 1-12
Title string `json:"title" colSpan:"col-span-12"` // Full width
FirstName string `json:"firstName" colSpan:"col-span-6"` // Half width
LastName string `json:"lastName" colSpan:"col-span-6"` // Half width
align
Alignment hint for the rendered field.
Total string `json:"total" align:"right"`
requiredWhen / optionalWhen
Conditional requiredness — the form treats the field as required (or optional) when the referenced condition holds.
Host string `json:"host" requiredWhen:"tlsEnabled"`
Port int `json:"port" optionalWhen:"useDefaults"`
$ref / type
Low-level schema overrides: point the property at an existing definition, or force a JSON type.
Context any `json:"context" $ref:"#/$defs/Context"`
Payload any `json:"payload" type:"object"`
enumTitles
Human-readable labels for enum values (comma-separated, positional).
Level string `json:"level" enum:"1,2,3" enumTitles:"Low,Medium,High"`
propertyOrder
Field display order.
Syntax: propertyOrder:"N"
Important: when the schema is generated by reflection from a Go struct, the generator overwrites propertyOrder with the field's declaration order — the tag has no effect. Order fields by declaring them in the desired order. The propertyOrder property only matters when you author raw schema JSON yourself (the Port.Schema override for runtime-shaped forms), where it is what the editor sorts on.
// Reflection: declaration order wins — this renders Name, Email, Comments
type Form struct {
Name string `json:"name"`
Email string `json:"email"`
Comments string `json:"comments"`
}
Type-Specific Tags
For Strings
| Tag | Purpose | Example |
|---|---|---|
minLength | Min characters | minLength:"1" |
maxLength | Max characters | maxLength:"255" |
pattern | Regex validation | pattern:"^[a-z]+$" |
format | Input type | format:"textarea" |
enum | Allowed values | enum:"a,b,c" |
language | Code language | language:"sql" |
For Numbers
| Tag | Purpose | Example |
|---|---|---|
minimum | Min value | minimum:"0" |
maximum | Max value | maximum:"100" |
default | Default value | default:"10" |
For Arrays
| Tag | Purpose | Example |
|---|---|---|
minItems | Min elements | minItems:"1" |
maxItems | Max elements | maxItems:"10" |
enumTitles | Labels for enum values | enumTitles:"Low,High" |
For Booleans
| Tag | Purpose | Example |
|---|---|---|
default | Default value | default:"true" |
format | Render style | format:"button" / format:"checkbox" |
Secrets
There is no ConfigRef type and no secret-reference tag. Sensitive values are entered through settings/control widgets; treat them as regular string fields.
Complete Example
type ServerSettings struct {
// Basic tab — declaration order controls display order
Name string `json:"name" required:"true" title:"Server Name" description:"Unique identifier for this server" minLength:"1" maxLength:"64" tab:"Basic"`
Host string `json:"host" required:"true" title:"Host" description:"Hostname or IP address" default:"0.0.0.0" tab:"Basic" colSpan:"col-span-8"`
Port int `json:"port" required:"true" title:"Port" description:"Port number (1-65535)" minimum:"1" maximum:"65535" default:"8080" tab:"Basic" colSpan:"col-span-4"`
// Security tab
TLSEnabled bool `json:"tlsEnabled" title:"Enable TLS" description:"Use HTTPS instead of HTTP" default:"false" tab:"Security"`
APIKey string `json:"apiKey" title:"API Key" description:"Secret API key for authentication" tab:"Security"`
// Advanced tab
Timeout string `json:"timeout" title:"Request Timeout" default:"30s" tab:"Advanced"`
MaxConnections int `json:"maxConnections" title:"Max Connections" minimum:"1" maximum:"10000" default:"100" tab:"Advanced"`
LogLevel string `json:"logLevel" title:"Log Level" enum:"debug,info,warn,error" enumTitles:"Debug,Info,Warning,Error" default:"info" tab:"Advanced"`
ConfigYAML string `json:"configYaml" title:"Extra Config" format:"code" language:"yaml" tab:"Advanced"`
}
// Control-port struct with buttons and read-only status
type Control struct {
Status string `json:"status" readonly:"true" title:"Status"`
Start bool `json:"start" format:"button" title:"Start" colSpan:"col-span-6"`
Stop bool `json:"stop" format:"button" title:"Stop" colSpan:"col-span-6"`
}
Quick Reference Table
| Tag | Purpose | Example |
|---|---|---|
json | JSON field name | json:"fieldName" |
required | Mark required | required:"true" |
title | Display label | title:"Field Label" |
description | Help text | description:"Help" |
default | Default value | default:"value" |
enum | Allowed values | enum:"a,b,c" |
minimum / maximum | Number range | minimum:"0" |
minLength / maxLength | String length | maxLength:"255" |
minItems / maxItems | Array size | minItems:"1" |
pattern | Regex pattern | pattern:"^[a-z]+$" |
readonly | Read-only | readonly:"true" |
format | Renderer: textarea, code, json, date-time, radiobox, base64, select, checkbox, button | format:"textarea" |
language | Code editor language | language:"yaml" |
tab | Group in tab | tab:"Advanced" |
colSpan | Grid width | colSpan:"col-span-6" |
align | Alignment hint | align:"right" |
configurable | Data-mappable per edge | configurable:"true" |
shared | Shareable definition | shared:"true" |
requiredWhen / optionalWhen | Conditional requiredness | requiredWhen:"tlsEnabled" |
$ref / type | Schema overrides | $ref:"#/$defs/Context" |
enumTitles | Enum labels | enumTitles:"Low,High" |
propertyOrder | Display order — raw Port.Schema JSON only; reflection overwrites it with declaration order | propertyOrder:"1" |