Tagex
Tagex is a Go library for executing behavior defined by struct tags. It lets you attach evaluation, mutation, and side effects directly to data structures in a controlled and reusable way.
Instead of treating struct tags as passive metadata, Tagex treats them as instructions: tags select what should run, directives define what it does, and the struct defines what success means.
What Problem Does Tagex Solve?
In many Go codebases, structs represent more than just data. They describe inputs, configuration, requests, and operational boundaries.
The logic associated with those structs is often scattered:
- Fields are checked in one place
- Values are modified in another
- Side effects are triggered manually
- Control flow is enforced with ad-hoc conditionals
Tagex provides a way to bring this logic back to where it belongs: next to the data it applies to, without turning structs into active objects or introducing a framework.
Core Concepts
Tags
A tag defines an execution context. It groups related directives and determines when they apply.
Tags are reusable across structs and intentionally lightweight. They do not define behavior on their own.
Directives
A directive is a unit of behavior. It may evaluate a field, mutate it, or interpret parameters attached to it.
Directives are reusable, composable, and explicitly scoped. They define their own semantics, including how their parameters are parsed.
Structs
The struct being processed defines intent.
It selects which tags apply, which directives run, and how the outcome of execution is handled.
Execution Model
Tagex operates as a small, explicit execution engine.
Processing always starts by calling ProcessStruct
with a pointer to a struct.
During execution:
- Struct fields are inspected for matching tags
- Directives are selected based on tag contents
- Each directive executes directly against its field
There is no intermediate representation, rule tree, or expression graph. Execution happens directly and deterministically.
ProcessStruct,
with optional struct-owned lifecycle hooks.
Optional Lifecycle Hooks
A struct may optionally define lifecycle hooks that are invoked before and after directive execution.
These hooks are struct-owned and entirely optional. Tagex does not interpret their meaning or enforce semantics.
- Before() — runs before directive execution begins
- Success() — runs after all directives complete successfully
- Failure(err) — runs if execution fails at any point
This allows the same tags and directives to be reused across structs, while each struct defines its own success and failure boundaries.
Execution, Not Interpretation
Tagex does not interpret intent or infer meaning. It executes exactly what is declared.
Execution is:
- Explicit
- Deterministic
- Locally scoped
There is no global state, no hidden lifecycle, and no implicit ordering beyond what is declared. Tagex is a small execution model that makes struct-attached behavior explicit, reusable, and predictable.
Next Steps
To see Tagex in action, start with the Getting started guide.
The Guides section explores the model in depth, including evaluation, mutation, pre- and post-processing, and directive-owned parsing.