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:

FormatApplies toDescription
textareastringMulti-line text input
codestringCode editor (pair with language)
jsonstringCode editor in JSON mode
date-timestringDate and time picker
radioboxstring/number + enumRadio group instead of dropdown
base64stringFile upload stored base64-encoded
selectstring/number + enumDropdown (default when enum present)
checkboxboolCheckbox
buttonboolClickable 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

TagPurposeExample
minLengthMin charactersminLength:"1"
maxLengthMax charactersmaxLength:"255"
patternRegex validationpattern:"^[a-z]+$"
formatInput typeformat:"textarea"
enumAllowed valuesenum:"a,b,c"
languageCode languagelanguage:"sql"

For Numbers

TagPurposeExample
minimumMin valueminimum:"0"
maximumMax valuemaximum:"100"
defaultDefault valuedefault:"10"

For Arrays

TagPurposeExample
minItemsMin elementsminItems:"1"
maxItemsMax elementsmaxItems:"10"
enumTitlesLabels for enum valuesenumTitles:"Low,High"

For Booleans

TagPurposeExample
defaultDefault valuedefault:"true"
formatRender styleformat:"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

TagPurposeExample
jsonJSON field namejson:"fieldName"
requiredMark requiredrequired:"true"
titleDisplay labeltitle:"Field Label"
descriptionHelp textdescription:"Help"
defaultDefault valuedefault:"value"
enumAllowed valuesenum:"a,b,c"
minimum / maximumNumber rangeminimum:"0"
minLength / maxLengthString lengthmaxLength:"255"
minItems / maxItemsArray sizeminItems:"1"
patternRegex patternpattern:"^[a-z]+$"
readonlyRead-onlyreadonly:"true"
formatRenderer: textarea, code, json, date-time, radiobox, base64, select, checkbox, buttonformat:"textarea"
languageCode editor languagelanguage:"yaml"
tabGroup in tabtab:"Advanced"
colSpanGrid widthcolSpan:"col-span-6"
alignAlignment hintalign:"right"
configurableData-mappable per edgeconfigurable:"true"
sharedShareable definitionshared:"true"
requiredWhen / optionalWhenConditional requirednessrequiredWhen:"tlsEnabled"
$ref / typeSchema overrides$ref:"#/$defs/Context"
enumTitlesEnum labelsenumTitles:"Low,High"
propertyOrderDisplay order — raw Port.Schema JSON only; reflection overwrites it with declaration orderpropertyOrder:"1"