Types

Vex infers most local types. Declare types for inputs, function signatures, and named record fields. Known record fields and call arguments are checked before a run; dynamic data still needs validation when you use it.

Common types

  • Values: str, int, float, bool, bytes, duration, size, null, and json.
  • Targets: host, url, cidr, address, and port.
  • Collections: list<T> (also T[]) and set<T>.
  • Choices: enum(fast, deep).
input endpoint: url
input targets: list<host>
input mode: enum(fast, deep) = fast

timeout = 500ms
budget = 10mb
options = { retries: 2, enabled: true }
out(options.retries)

Durations use ms, s, m, or h; sizes use mb or gb. Use typed inputs for target values: a general str is not interchangeable with a host or url, nor is an int interchangeable with a port.

Collections and records

Lists use square brackets. Records use named fields; sets use braces without field names. List indexes start at zero. A range slice includes both endpoints.

ports = [80, 443, 8080]
first = ports[0]
first_two = ports[0..1]
labels = {"web", "api"}
service = { name: "web", port: first }
out(service.name)

Declare a reusable record shape with struct, then construct it using named arguments:

struct Service { name: str, port: int }
service = Service(name="web", port=443)
out(service)

Some modules return reusable objects such as HTTP clients or sessions rather than records. Follow that module’s documented methods and lifecycle. Use vex_help in your environment for exact parameter and return types.

Improve team velocity with
better security and privacy.