Syntax & Directives¶
All dotenv-fusion directives start with #@ to remain compatible with standard dotenv loaders.
Quick reference¶
| Directive | Purpose | Example |
|---|---|---|
#@import | Import another file | #@import database.env prefix=DB_ |
#@schema | Load an external contract | #@schema application.env-schema |
#@def | Define variable constraints | #@def PORT type=int default=3000 |
#@if | Conditional block | #@if ${ENV} == production |
#@ifdef | Test if variable exists | #@ifdef CI |
#@ifndef | Test if variable doesn't exist | #@ifndef LOCAL |
#@else | Alternative block | #@else |
#@endif | Close conditional | #@endif |
#@mode | Change processing modes | #@mode override=true strict=true |
Variable expansion¶
# Basic syntax
BASE_URL=https://api.example.com
API_URL=${BASE_URL}/v1
# Default values
PORT=${PORT:-3000}
# System environment
HOME_DIR=${HOME}/app
Syntax: ${VAR}, $VAR, ${VAR:-default}
Import directive¶
# Simple import
#@import database.env
# With prefix
#@import database.env prefix=DB_
# Optional (no error if missing)
#@import .env.local mode=ifexist
# Override existing values
#@import overrides.env override=true
# Dynamic paths
#@import configs/${ENV}.env
Conditionals¶
# If/else
#@if ${ENV} == production
LOG_LEVEL=error
#@else
LOG_LEVEL=debug
#@endif
# Existence check
#@ifdef CI
CI_MODE=true
#@endif
#@ifndef LOCAL
REMOTE=true
#@endif
Operators: ==, !=, >, <, >=, <=
Variable definitions¶
# Type system
#@def PORT type=int default=3000
#@def DEBUG type=bool default=false
#@def TAGS type=list
#@def CONFIG type=json
#@def ENV type=enum values=development,staging,production
# Numeric and length constraints
#@def PORT type=int min=1 max=65535
#@def APP_NAME type=str nonempty=true min_length=3 max_length=80
# Local URL validation (no network request or DNS lookup)
#@def API_URL type=str format=url schemes=https
# Validation
#@def EMAIL validate=^[\w.-]+@[\w.-]+\.\w+$
# Required variables
#@def API_KEY required=true
# Secrets (masked in verbose mode)
#@def TOKEN secret=true
# Override a false positive from name-based secret detection
#@def PUBLIC_KEY secret=false
# Lazy variables (kept as ${VAR} in fuse output)
#@def EXTERNAL_TOKEN lazy=true
# Documentation
#@def PORT doc="HTTP listening port"
# Secret sourced from a key in an age-encrypted dotenv bundle
#@def DB_PASSWORD required=true source="age://store/database.env.age#PASSWORD"
Types: int, float, bool, str, list, json, enum
Options: type, default, required, validate, secret, lazy, source, doc, values, min, max, nonempty, min_length, max_length, format, schemes. secret=true forces masking, secret=false disables automatic detection for that variable, and omitting the option keeps name-based detection enabled.
Definitions can stay inline or move to a dedicated schema:
See Define a Shared Schema for the schema grammar, imports, duplicates, confinement, and migration.
source= makes the variable secret and obtains its value from a backend. The first available backend is age:
# Explicit selector
#@def DB_USERNAME source="age://store/database.env.age#USERNAME"
# Without a fragment, the final variable name is the selector
#@def DB_PASSWORD source="age://store/database.env.age"
A sourced definition cannot also use an inline assignment, default=, lazy=true, or secret=false. Variables derived from a source are secret and masked transitively. Sources are not available to #@import paths or conditional directives because resolution happens after the configuration structure is built.
See Get Started with age for store configuration and execution.
Quote behavior¶
# Double quotes: expansion + escape sequences
MESSAGE="Hello ${NAME}\nWelcome"
# Single quotes: literal (no expansion)
PATTERN='${NOT_EXPANDED}'
# No quotes: expansion + comments removed
DEBUG=true # Comment removed
Processing modes¶
# Enable override mode: later definitions override earlier ones
#@mode override=true
# Enable strict mode: undefined variables cause errors
#@mode strict=true
# Combine both on one line
#@mode override=true strict=true
# Reset to defaults
#@mode override=false strict=false
Available modes:
override=true/false- When true, variable definitions override existing values (default: no, first-wins)strict=true/false- When true, undefined variables raise errors instead of becoming empty (default: no)
By default, undefined variables become empty strings and first definition wins.
→ See CLI Commands for detailed documentation and all options.