Active mode

Last updated: 2026-10-14Markers, constraints, environment variables, secrets, includes and interpolation — a config that resolves itself.

Active mode

Mirrored from the format repository — docs/spec/SPECIFICATION_EN.md, SYNX 3.7.4. Changes are made there.

3.1 What Is It

By default a .synx file contains static data. Just keys and values, like JSON.

But if the first line of the file says !active, the file becomes a live config — enabling:

  • Functions (:random, :calc, :env, etc.)
  • Constraints ([min:3], [type:int], etc.)
synx
!active

port:env PORT
greeting:random
  - Hello!
  - Welcome!

Without !active — markers :random, :calc and square brackets [] are completely ignored. The parser reads the file as plain text:

synx
// No !active — functions DO NOT work
port:env PORT           // key = "port:env", value = "PORT" (just a string)
greeting:random          // key = "greeting:random", value = {} (object)

💡 This is a security feature: a static file will never execute code, access environment variables, or run commands.


3.2 Full List of Functions (:)

Functions are written with a colon immediately after the key name: key:function value.


:random — Random Selection

Selects one element from a list on each parse.

Equal chances (no percentages):

synx
!active

battle_cry:random
  - Time to win!
  - Ha-ha-ha!
  - For the Syndicate!

Each item has a 33.3% chance.

Weighted random (with percentages):

synx
!active

// Percentages go after :random separated by spaces
// Order of percentages matches order of items
loot:random 70 20 10
  - Common Chest
  - Rare Chest
  - Legendary Chest

Here:

  • "Common Chest" drops with 70% chance
  • "Rare Chest" — 20%
  • "Legendary Chest" — 10%

Percentage rules:

SituationBehavior
No percentagesAll items are equally likely
Sum = 100Used as-is
Sum ≠ 100Automatically normalized (proportions preserved)
Fewer percentages than itemsRemainder is split evenly among items without a percentage
More percentages than itemsExtra percentages are ignored

Normalization example:

synx
!active

// 2 + 1 = 3, normalized: ~66.7% and ~33.3%
class:random 2 1
  - Warrior
  - Mage

Partial percentages example:

synx
!active

// First gets 80%, remaining 20% split between two: 10% each
drop:random 80
  - Nothing
  - Sword
  - Shield

:calc — Expression Evaluation

Evaluates an arithmetic expression. Can reference other keys by name.

synx
!active

price 100
tax:calc price * 0.2
total:calc price + tax

Result:

price 100
tax 20    // ← your program receives this value
total 120 // ← your program receives this value

As a JSON file:

json
{
  "price": 100,
  "tax": 20,
  "total": 120
}

Supported operations: +, -, *, /, % (remainder), (, ).

⚠️ Arithmetic only. No arbitrary code. The parser uses a safe evaluator, not eval().


:env — Environment Variable

Substitutes the value of a system environment variable.

synx
!active

port:env PORT
home_dir:env HOME

If the variable is not found — the value will be null.

With a default (via :default):

synx
!active

port:env:default:8080 PORT

If PORT is not set → returns 8080.

Keeping text as text. The variable's value is cast like any literal (8080 → int). Values that only look numeric — 64-bit ids, zero-padded codes — keep their text with a (string) hint or a [type:string] constraint; the same rule applies to the :default fallback:

synx
!active

discord_app_id[type:string]:env DISCORD_APP_ID
zip(string):env:default:007 ZIP
api_key[type:string]:secret:env API_KEY

Since 3.7.4 [type:string] keeps the text too. Earlier only (string) did: the value was cast first, so [type:string] rejected the resulting number with CONSTRAINT_ERR. A :secret value satisfies [type:string].


:alias — Reference to Another Key

Copies the value of another key. Does not duplicate data — references it.

synx
!active

admin_email alex@example.com
complaints_email:alias admin_email

Result:

json
{
  "admin_email": "[email protected]",
  "complaints_email": "[email protected]"
}

:secret — Hidden Value

The value is readable by your program but not shown in logs, during freeze, or when serialized to JSON. Protects against accidental leaks.

synx
!active

api_key:secret sk-1234567890abcdef
db_password:secret P@ssw0rd!

With console.log(data), print(data), JSON.stringify(data) — shows "[SECRET]".
To get the real value, use the .reveal() method:

javascript
// JavaScript / TypeScript
const key = data.api_key;          // SynxSecret object
console.log(String(key));           // "[SECRET]"
console.log(JSON.stringify(key));   // '"[SECRET]"'
console.log(key.reveal());          // "sk-1234567890abcdef"  ← real value
python
# Python
key = data['api_key']               # SynxSecret object
print(key)                          # [SECRET]
print(key.reveal())                 # sk-1234567890abcdef  ← real value

Since 3.7.2 the mask also holds for util.inspect / console.log of a whole object, object spread and Object.entries (TypeScript), for {:?} (Rust), and for the payload handed to WASM marker plugins.

⚠️ Important: Never log the result of .reveal(). This method is intended only for passing the value to APIs, database connections, etc.


:default — Default Value

Sets a fallback if the main value is empty or not found. Most often combined with :env.

synx
!active

// If PORT env var is not set — will be 3000
port:env:default:3000 PORT

// Just a default value (if value = null or empty)
theme:default dark

:unique — Remove Duplicates from List

Keeps only unique elements.

synx
!active

tags:unique
  - action
  - rpg
  - action
  - simulation
  - rpg

Result: ["action", "rpg", "simulation"]


:include — Include Another File

Inserts the contents of another .synx file into the current one. Path is relative to the current file.

synx
!active

// Pull database settings from a separate file
database:include ./db.synx

Where db.synx:

synx
host localhost
port 5432
name mydb

Result:

json
{
  "database": {
    "host": "localhost",
    "port": 5432,
    "name": "mydb"
  }
}

:geo — Value by Geolocation / Region

Selects a value based on user region (determined by IP or system locale).

synx
!active

currency:geo
  - US USD
  - EU EUR
  - GB GBP

This function requires runtime support. The parser passes the current region to the engine.


:template — String Interpolation

Substitutes {placeholders} with values from other keys. Supports dot-path for nested access.

synx
!active

first_name John
last_name Doe
greeting:template Hello, {first_name} {last_name}!

Result: "Hello, John Doe!"

With nested references (dot-path):

synx
!active

server
  host localhost
  port 8080

db_url:template http://{server.host}:{server.port}/db

Result: "http://localhost:8080/db"


:split — Split String into Array

Splits a string by a delimiter into an array of items. Auto-casts values if they look like numbers.

Default delimiter (comma):

synx
!active

colors:split red, green, blue

Result: ["red", "green", "blue"]

With delimiter keyword:

synx
!active

// Space delimiter
words:split:space hello world foo

// Pipe delimiter
flags:split:pipe read write execute

Supported delimiter keywords: space, pipe, dash, dot, semi, tab

Auto-casting:

synx
!active

numbers:split 1, 2, 3

Result: [1, 2, 3] (auto-detected as integers)


:join — Join Array into String

Joins array elements into a string with a delimiter.

Default delimiter (comma):

synx
!active

tags:join
  - action
  - rpg
  - adventure

Result: "action, rpg, adventure"

With delimiter keyword:

synx
!active

path:join:slash
  - home
  - user
  - documents

Result: "home/user/documents"


:ref — Reference and Chain

Resolves a key by name and passes the value to subsequent markers in the chain. Similar to :alias, but designed for chaining with :calc and other transformations.

synx
!active

base_rate 100
adjusted:ref:calc:*2 base_rate

Result: adjusted = 200. The shorthand :ref:calc:*2 base_rate resolves base_rate → 100, then computes 100 * 2.


:i18n — Internationalization

Selects a translated value based on the runtime locale. Child keys are language codes; the engine picks the one matching options.lang (defaults to en).

synx
!active

greeting:i18n
  en Hello
  ru Привет
  de Hallo

Pluralization — append the count field name: :i18n:count_field

synx
!active

items_label:i18n:item_count
  en
    one {count} item
    other {count} items
  ru
    one {count} предмет
    few {count} предмета
    many {count} предметов
    other {count} предметов

Plural categories follow CLDR rules (en: one/other, ru: one/few/many/other). {count} is substituted with the referenced field's value.


:clamp — Numeric Range Clamping

Clamps a numeric value to a minimum–maximum range.

synx
!active

volume:clamp:0:100 150
# → 100

brightness:clamp:0:255 -10
# → 0

Error if MIN > MAX.


:round — Numeric Rounding

Rounds a numeric value to N decimal places.

synx
!active

price:round:2 19.999
# → 20.00

pi:round:4 3.14159265
# → 3.1416

whole:round:0 42.7
# → 43

Default: 0 decimal places (rounds to integer).


:format — Printf-Style Formatting

Formats a value using a printf-style pattern.

synx
!active

price:format:%.2f 19.9
# → "19.90"

code:format:%04d 42
# → "0042"

Supported patterns: %.Nf (float), %d (int), %0Nd (zero-padded). Max width/precision: 4096/1024.


:map — Lookup Table

Maps a value through a lookup table. Child list items are lookup_value result_text pairs.

synx
!active

status_labels
  200 OK
  404 Not Found
  500 Internal Server Error

result:map:status_labels
  - 200
  - 404
  - 500

Result: ["OK", "Not Found", "Internal Server Error"]. If no match found, returns null.


:once — Generate Once, Cache

Generates a value once at first parse and caches it in a .synx.lock sidecar file for subsequent reads.

synx
!active

instance_id:once:uuid
# → "550e8400-e29b-41d4-a716-446655440000" (stable across parses)

created_at:once:timestamp
# → "2026-04-01T12:00:00Z" (frozen at first parse)

Types: uuid, timestamp, random.


:version — Version Comparison

Compares a value against a semantic version constraint. Returns a boolean.

synx
!active

app_ok:version:>=:1.0.0 1.2.3
# → true

engine_ok:version:>=:2.0.0 1.9.5
# → false

Operators: >=, <=, >, <, ==, !=. Parses semver (x.y.z…).


:watch — Read External File

Reads an external JSON or SYNX file at parse time and injects its content as the value.

synx
!active

all_flags:watch ./flags.synx
db_host:watch:database.host ./infra.json

Optional key path after :watch: extracts a specific nested value. Max depth: 16, max size: 10 MiB. Path-jail enforced.


:fallback — File Fallback

If the primary source file is missing, uses the fallback path instead.

synx
!active

config:fallback:./defaults.synx ./overrides.synx

Also applies if the value is null or empty.


:spam — Rate Limiting

Limits how many times a value can be accessed within a time window.

synx
!active

api_endpoint:spam:5:60 https://api.example.com/data
# Max 5 accesses per 60 seconds

Window defaults to 1 second if omitted. The counter lives in process memory and resets on restart.


:prompt — LLM Prompt Label

Formats a subtree as a labeled code fence for LLM consumption.

synx
!active

config_block:prompt:AppConfig
  app_name MyCoolApp
  version 2.1.0

Output: `AppConfig (SYNX):\n```synx\n...\n````


:vision — Image Metadata (pass-through)

Marks a value as an image reference for vision model input. No engine transformation — applications detect via metadata.

synx
!active
diagram:vision ./docs/architecture.png

:audio — Audio Metadata (pass-through)

Marks a value as an audio reference for audio model input. No engine transformation — applications detect via metadata.

synx
!active
recording:audio ./meetings/standup.mp3

:import — Alias for :include

Identical to :include. Use whichever reads more naturally.

synx
!active
db:import ./config/db.synx

:inherit — Object Inheritance (Mixin)

Inherits all fields from one or more parent objects. Child fields take priority.

synx
!active

base
  host localhost
  port 8080
  debug false

production:inherit base
  host prod.example.com
  debug false

Result: production = { "host": "prod.example.com", "port": 8080, "debug": false }. Parents are merged left to right, then child overrides. Resolved in a pre-pass before other markers.


3.3 Functions Summary Table

FunctionDescriptionExample
:randomRandom item from listphrase:random
:random N N NWeighted random (percentages)loot:random 70 20 10
:calcArithmetic evaluationtotal:calc price * 1.2
:envEnvironment variableport:env PORT
:aliasReference to another keycopy:alias original
:secretValue hidden from logspassword:secret abc123
:defaultDefault valuetheme:default dark
:default:XFallback (in combination)port:env:default:8080 PORT
:uniqueList deduplicationtags:unique
:includeInclude external filedb:include ./db.synx
:importAlias for :includedb:import ./db.synx
:geoValue by regioncurrency:geo
:templateString interpolationgreeting:template Hello, {name}!
:splitString → arraycolors:split red, green, blue
:joinArray → stringtags:join
:refResolve and chainadjusted:ref:calc:*2 base_rate
:i18nTranslation by localegreeting:i18n
:clampNumeric clampingvolume:clamp:0:100 150
:roundNumeric roundingprice:round:2 19.999
:formatPrintf-style formattingprice:format:%.2f 19.9
:mapLookup tableresult:map:status_labels
:onceGenerate once, cacheid:once:uuid
:versionVersion comparisonok:version:>=:1.0.0 1.2.3
:watchRead external fileflags:watch ./flags.synx
:fallbackFile fallbackcfg:fallback:./default.synx ./custom.synx
:spamRate limitingapi:spam:5:60 endpoint
:promptLLM prompt labelctx:prompt:system Your instructions
:visionImage metadataimg:vision ./photo.png
:audioAudio metadatasnd:audio ./clip.mp3
:inheritObject inheritanceprod:inherit base

Chaining functions — via : chain:

synx
!active
port:env:default:8080 PORT

3.4 Constraints ([]) — Data Validation

Constraints are written in square brackets between the key and the function (or value). They only work in !active mode.

General syntax:

key[constraint1:value, constraint2:value]:function value

min / max — Minimum and Maximum

For numbers — restricts the value range.
For strings — restricts the length (character count).

synx
!active

// String from 3 to 30 characters
app_name[min:3, max:30] TotalWario

// Number from 1 to 100
volume[min:1, max:100] 75

// Minimum only
password[min:8] mypassword123

required — Required Field

The parser will throw an error if the value is empty or missing.

synx
!active

api_key[required]:env API_KEY
name[required, min:1] Wario

pattern — Regular Expression

The value must match a regex pattern.

synx
!active

country_code[pattern:^[A-Z]{2}$] US
phone[pattern:^\+\d{10,15}$] +12025551234

enum — Allowed Values

The value must be one of the listed options.

synx
!active

theme[enum:light|dark|auto] dark
region[enum:EU|US|GB|AS] US

readonly — Read Only

The value cannot be changed via API / hot-reload of the config. Only manual file editing.

synx
!active

version[readonly] 2.0.0

3.5 Constraints Summary Table

ConstraintDescriptionSyntax
minMinimum (length in characters, or value)[min:3]
maxMaximum (length in characters, or value)[max:100]
typeData type[type:int]
requiredRequired field[required]
patternRegex validation[pattern:^\d+$]
enumList of allowed values[enum:a|b|c]
readonlyModification forbidden[readonly]

A string's length is its number of Unicode characters (scalar values): мир and 東京都 are 3, 😀 is 1. Until 3.7.4 the Rust engine counted UTF-8 bytes.

A failed constraint replaces the value with a CONSTRAINT_ERR: … string. Constraints are also collected by field name across the whole document — the strictest declaration wins — and checked against every field of that name once all markers are resolved. A pattern that nests one quantifier inside another (^(a+)+$) is skipped rather than run, so a hostile document cannot stall the parser.

Constraints can be combined with commas:

synx
!active
password[required, min:8, max:64, type:string] MyP@ssw0rd

3.6 Directives

Directives are top-level lines that begin with ! or #!. They control the document's mode and metadata. A directive must appear before any key-value lines.

DirectiveDescription
!activeEnable markers, constraints, and validation (see §3.1)
!lockMark document as read-only (metadata flag)
!includeInclude another SYNX file at the document root level
!toolReshape output as a tool-call envelope (name + params)
!schemaExport a JSON Schema Draft 2020-12 from the document structure
!llmAnnotate document for LLM consumption (metadata-only)

!lock — Read-Only Hint

Sets the locked flag on the parse result. The data tree is unchanged — it is advisory metadata for tooling.

synx
!lock

name Alice
role admin

!include — Document-Level Include

Includes another SYNX file and merges its contents at the root level. An optional alias assigns the included tree to a named key.

synx
!include ./db.synx
!include ./auth.synx auth_config

name MyApp

Maximum depth: 16. Path-jail security prevents .. escapes.

!tool — Tool Call Envelope

Reshapes the output: the first key becomes the tool name, its children become parameters.

synx
!tool

web_search
  query rust async
  lang en
  results 10

Output:

json
{
  "tool": "web_search",
  "params": {
    "query": "rust async",
    "lang": "en",
    "results": 10
  }
}

!schema — JSON Schema Export

Causes the parser to emit a JSON Schema Draft 2020-12 object derived from the document's keys and constraints.

synx
!schema

name[required, type:string]
port[type:int, min:1, max:65535]

!llm — LLM Metadata

Metadata-only directive for LLM tooling. Does not change the parsed data tree.

synx
!llm

persona Assistant
role You are a helpful coding assistant
tone professional and concise
Active mode | AS Docs