Skip to content

Struct Tags

Struct tags are the primary CLI contract in flags. They describe how a Go field is exposed to the command line, how it is shown in help, where defaults can come from, and which validation rules run after parsing.

Tags are read when the parser scans the struct. Runtime setters can still change metadata after scanning, but tags should remain the default place for stable CLI behavior.

Tag Syntax

Use ordinary Go struct tags:

type Options struct {
  Verbose bool `short:"v" long:"verbose" description:"Show verbose output"`
}

Boolean tags accept common boolean spellings: true, false, yes, no, y, n, 1, 0, on, off.

List-like tags use the parser tag-list delimiter. The default delimiter is ;. Use Parser.SetTagListDelimiter(',') if your project needs comma-separated lists in tags.

Tag Applicability

Most tags are tied to one field kind. Use this as the quick map before reading the detailed sections:

  • option fields use identity, value, default, environment, relation, I/O, validation, INI, completion, visibility, and deprecation tags;
  • command fields use command, alias, command group, description, visibility, immediate, ordering, INI group, pass-through, and deprecation tags;
  • group fields use group, namespace, description, visibility, immediate, and INI group tags;
  • positional argument fields use positional name, description, required, default, I/O, completion, and validation tags;
  • positional argument container structs use positional-args.

Invalid tag and field-kind combinations fail during parser construction or validation with ErrInvalidTag.

Option Identity

short defines a one-rune option name. It is used as -v, or as a combined short option such as -vvv when parsing allows that form.

long defines the canonical long option name. It is used as --verbose. Long names are also used by environment auto-derivation, INI keys, generated help, docs, and completion output.

An option field should normally define at least long. A field without short and without long may still be scanned, but it is not practically addressable from the command line.

short-alias and long-alias add one additional name each. They can be repeated in multi-tags.

short-aliases and long-aliases add several aliases through the list delimiter. Use plural aliases for new code when all aliases are known at once. Use repeatable singular aliases when aliases are generated by code.

User Text

description is the short text shown in help and generated docs. Keep it useful as a single sentence.

description-i18n is the localization key for description. When the active catalog contains the key, localized text is used instead of the literal tag text.

long-description is extended prose for generated documentation and rich help contexts. Use it when the option needs more than one short sentence.

long-description-i18n is the localization key for extended text.

value-name controls the placeholder shown for option values. For example, value-name:"FILE" renders as --output=FILE.

value-name-i18n localizes that placeholder. Use it when generated help must be translated consistently.

Required and Optional Values

required makes an option or positional argument mandatory. Required checks run after defaults and environment values are applied. A required option with a usable default is considered satisfied.

Scalar options use boolean required values. Repeatable options and trailing positional slices can also use numeric forms. For those fields, required:"N" means at least N values, and required:"N-M" means from N to M values.

optional changes option argument parsing so the option can appear without an explicit value. For long options, prefer --flag=value when a value is present. This avoids ambiguity with the next positional argument.

optional-value is the value assigned when an optional option appears without an explicit value. For example, it can map --color to auto while still allowing --color=always.

Defaults and Environment

default adds one default value. It can be repeated for slices and maps.

defaults adds several default values through the tag-list delimiter. Do not mix default and defaults on the same field unless the intended combined order is obvious to readers.

default-mask changes how the default is displayed in help and docs. Use it when the display text should differ from the actual default. A mask of - hides the default display completely.

secret:"true" marks option values as sensitive. The parser keeps the real value in the target struct, but built-in help, docs, INI output, completion choices, and parser errors render sensitive values as ***. Names such as the flag, env key, and INI key remain visible.

env declares an environment variable used as a fallback source. The environment value is applied before required validation.

auto-env derives an environment variable name from the long option name. Use it for consistent large CLIs where every option should have a predictable environment override.

env-delim splits environment values for slices and maps. For example, env-delim:"," can parse A,B,C into []string.

Value Constraints

choice adds one allowed value. It can be repeated.

choices adds several allowed values through the tag-list delimiter. Choices are checked after a value is parsed into the target type. They also feed completion when no custom completer is available.

base sets the radix for integer parsing. Use it for values such as octal file modes or hexadecimal masks.

key-value-delimiter changes the delimiter for map entries. The default delimiter is :.

unquote controls automatic unquoting of string values. Set it to false when the application needs to receive quote characters exactly as passed.

terminator makes an option consume arguments until the terminator token. This is useful for find -exec style options. The target is usually a slice.

Option Relations

xor declares mutually exclusive option relation groups. If two options from the same command-local group are set together, parsing fails.

With required on a member of an xor group, the group must contain exactly one set option. Without required, zero or one option is allowed.

and declares all-or-none option relation groups. If any option in the group is set, all options in that group must be set.

With required on a member of an and group, the empty group is not allowed, so all members become required as a group. Without required, either no member or every member is allowed.

Relation groups are command-local. A group name on one command does not conflict with the same group name on another command.

Counter Options

counter enables integer counter mode. Each occurrence increments the field by one. An explicit non-negative numeric value increments by that value.

type Options struct {
  Verbose int `short:"v" long:"verbose" counter:"true"`
}

Supported forms include -vvv, -v -v -v, --verbose=3, and -v=3. Counter targets must be integer or unsigned integer fields. Negative increments are rejected.

I/O Template Tags

io assigns an I/O role. Supported roles are in and out.

io-kind describes what kind of value is expected. Supported kinds are auto, stream, file, and string.

io-stream selects the stream token used for stream values. Supported values are stdin, stdout, and stderr.

io-open stores output file open metadata. Supported values are truncate and append. It is valid only for io:"out".

I/O tags apply to string options and string positional arguments. They do not open files by themselves. They normalize CLI conventions such as - for standard streams, and they provide metadata that application code can use consistently.

Validation Tags

Validation tags apply to option fields and positional argument fields. They run after parsing, defaults, and environment values.

String and path validators:

  • validate-existing-file requires an existing regular file.
  • validate-existing-dir requires an existing directory.
  • validate-readable requires the path to be readable.
  • validate-writable requires the path or parent directory to be writable.
  • validate-non-empty rejects strings that are empty after trimming spaces.
  • validate-regex requires the whole string to match the regular expression.
  • validate-min-len requires a minimum string length in runes.
  • validate-max-len requires a maximum string length in runes.
  • validate-path-abs requires an absolute path.

Numeric validators:

  • validate-min requires a minimum numeric value.
  • validate-max requires a maximum numeric value.

The validator target type must match the rule. String validators require string or []string. Numeric validators require numeric scalar or numeric slice types.

Rendering and Visibility

no-flag excludes a field from command-line flag parsing. The field can still be useful for config-only values, internal data, or structs shared with other systems.

hidden keeps an option, command, or group parseable, but removes it from help, completion, and generated docs.

deprecated marks an option or command as deprecated. The tag value is a short replacement hint shown in help and in parse warnings. Deprecated entities remain parseable. When a deprecated option or command is used during parsing, the parser emits a localized warning to standard error.

immediate marks an option, command, or group as a control-flow trigger. When an immediate option is set, required checks and command execution are skipped. This is appropriate for help, version, completion, and similar exits.

order sets explicit render priority. Use it when help output should stay stable even if struct field order changes.

completion sets a completion hint. Supported hints are file, dir, and none. Choices and custom completers take precedence.

INI Tags

ini-name changes the key used by INI parse/write logic. It does not change the command-line option name.

ini-group changes the INI section token for group or command blocks. Use it when CLI names and config-file section names should differ.

no-ini excludes a field from INI parsing and writing. Use it for runtime-only values, secrets supplied externally, or values that do not belong in persisted config.

Group Tags

group turns a nested struct into an option group. The tag value is the group heading in help and docs.

group-i18n is the localization key for the group heading.

namespace prefixes long option names inside the group hierarchy. This is useful for structured options such as --logging.level.

env-namespace prefixes environment variable names inside the group hierarchy. Use it when grouped options should also have grouped env names.

Group fields may also use description, description-i18n, long-description, long-description-i18n, hidden, and immediate.

Command Tags

command turns a struct field into a subcommand. The tag value is the command name.

command-i18n is the localization key for command short description text.

command-group groups commands in help and generated docs. It affects rendering only. It does not change parse behavior.

alias adds one additional command name. It can be repeated.

aliases adds several command aliases through the tag-list delimiter.

subcommands-optional allows a command with child commands to be selected without requiring a child command.

pass-after-non-option changes command-local parsing so option parsing stops after the first non-option argument. This is useful for wrapper commands that pass the rest to another program.

Command fields may also use description, description-i18n, long-description, long-description-i18n, hidden, immediate, and order.

Positional Argument Tags

positional-args marks a struct as a positional argument container. Fields inside that struct are consumed in declaration order.

positional-arg-name sets the placeholder name shown in help.

arg-name-i18n localizes the placeholder name.

arg-description-i18n localizes positional argument description text. If arg-description-i18n is not set, description-i18n can provide the same localized description.

description sets positional argument description text.

required on a positional field makes it mandatory. Trailing positional slices support numeric required forms.

io, io-kind, io-stream, io-open, completion, and validation tags can be used on string positional fields.

Tag Customization

Parser.SetTagPrefix("flag-") maps all tag names to prefixed names. This avoids collisions when a struct is shared with another package.

type Options struct {
  Verbose bool `flag-short:"v" flag-long:"verbose"`
}

Parser.SetFlagTags(...) can override individual tag names. Use it when only a few tags conflict with another schema.

Start with flags.NewFlagTags() for default names, or flags.NewFlagTagsWithPrefix("flag-") when every tag should share the same prefix. Then override only the fields that differ from the default mapping.

Parser.SetTagListDelimiter(...) changes the delimiter for list tags such as defaults, choices, aliases, short-aliases, and long-aliases.

Tags vs Runtime Setters

Prefer tags for stable CLI contracts. Prefer runtime setters for generated metadata, localized text wiring, or application-specific defaults discovered during startup.

Do not hide too much behavior in Configurer code. A reader should be able to understand the public CLI shape from the struct before reading integration logic.