@env-spec Reference
Config Items
Section titled “Config Items”Config items define individual env vars.
- Each has a key, an optional value, and optional attached comments
- Keys must start with
[a-ZA-Z_]
, followed by any of[a-ZA-Z0-9_]
— ✅SOME_ITEM
, ❌BAD-KEY
, ❌2BAD_KEY
- Setting no value is allowed and will be treated as
undefined
—UNDEF_VAR=
- An explicit empty string is allowed —
EMPTY_STRING_VAR=""
- Single-line values may be wrapped in quotes or not, and will follow the common value-handling rules (see below)
- Multi-line string values may be wrapped in either
( ' | " | """ | ``` )
- but we strongly recommend using triple backticks only for consistency
NO_VALUE=EMPTY_STRING_VALUE=""UNQUOTED_VALUE=asdfQUOTED_VALUE="asdf"FN_VALUE=fn(foo, "bar")MULTILINE_VALUE=```multiplelines```
Comments and @decorators
Section titled “Comments and @decorators”Comments in env-spec (like traditional .env files) start with a #
. Unlike traditional .env files, comments may contain additional metadata by using @decorators
, which may be attached to specific config items, sections, or the entire document.
- Comments can be either on their own line, or at the end of a line after something else
- Leading whitespace after the
#
is optional, but a single space is recommended - If a comment line starts with a @decorator, it will be considered a decorator comment line
- Otherwise it is a regular comment line and any contained @decorators will be ignored
- A decorator comment line may contain multiple decorators
- A decorator comment line may end with an additional comment, in which decorators will be ignored
- A post-value comment may also contain decorators, but is not recommended
# ❌ leading space makes this invalid# this is a regular comment line# @dec2 @dec2=foo # this is a decorator comment lineFOO=val # this is a post-value commentBAR=val # @dec # post-value comments may also contain decorators
# regular comment lines @ignore contained @decorators# @dec # as are @decorators within an extra comment after a decorator comment lineBAZ= # @dec # this is @ignored too
Decorators
Section titled “Decorators”Decorators are used within comments to attach structured data to specific config items, or within a standalone comment blockto alter a group of items or the entire document and loading process.
- Each decorator has a name and optional value (
@name=value
) or is a bare function call@func()
- Decorators with values may only be used once per comment block, while function calls may be used multiple times
- Using the name only is equivalent to setting the value to true —
@required
===@required=true
- Multiple decorators may be specified on the same line
- Decorator values will be parsed using the common value-handling rules (see below)
# @willBeTrue @willBeFalse=false @explicitTrue=true @undef=undefined @trueString="true"# @int=123 @float=123.456 @willBeString=123.456.789# @doubleQuoted="with spaces" @singleQuote='hi' @backTickQuote=`hi`# @unquoted=this-works-too @withNewline="new\nline"# @funcCallNoArgs=func() @dec=funcCallArray(val1, "val2") @dec=funcCallObj(k1=v1, k2="v2")# @anotherOne # and some comments, this @decorator is ignored# this is a comment and this @decorator is ignored
Dividers
Section titled “Dividers”A divider is a comment that serves as a separator, like a <hr/>
in HTML.
- A comment starting with
---
or===
is considered a divider —# ---
,# ===
- A single leading whitespace is optional (but recommended —
# ---
,#---
) - Anything after that is ignored and valid —
# --- some info
,# ------------
# the header comment block (see below) must end with a divider# ---ITEM1=ITEM2=# --- another divider ---ITEM3=
Config Item Comments
Section titled “Config Item Comments”Comment lines directly preceeding an item will be attached to that item, along with the decorators contained within.
- A blank line or a divider will break the above comments from being attached to the item
- Both decorator and regular comment lines may be interspersed
- Post-value comments may also contain decorators, but is not recommended
# these comments are attached to ITEM1 below# @dec1 @dec2 # meaning these decorators will affect the item# additional comments can be interspersed with decoratorsITEM1= # @dec3 # and a post-value comment can be used too
# not attached due to blank line
# also not attached due to divider# ---ITEM2=
Comment blocks & document header
Section titled “Comment blocks & document header”A comment block is a group of continuous comments that is not attached to a specific config item.
- The comment block is ended by an empty line, a divider, or the end of the file
- A comment block that is the first element of the document and ends with a divider is the document header
- Decorators from this header can be used to configure all contained elements, or the loading process itself
# this is the document header and usually contains root decorators# which affect default settings and the behavior of the tool that will be parsing this file# @dec1 @dec2# ---
# this is another comment block# and is not attached to an item
# this comment is attached to the item belowITEM1=
Common rules
Section titled “Common rules”Value handling
Section titled “Value handling”Values are interpreted similarly for config item values, decorator values, and values within function call arguments. Values may be wrapped in quotes or not, but handling varies slightly:
Unquoted values
Section titled “Unquoted values”- Will coerce
true
,false
,undefined
—@foo=false
- Will coerce numeric values —
@int=123 @float=123.456
- May be interpreted as a function call (see below)
- Otherwise will be treated as a string
- May not contain other characters depending on the context:
- config item values - may not contain
#
- decorator values - may not contain
[ #]
- function call arg values - may not contain
[),]
- config item values - may not contain
Quoted values
Section titled “Quoted values”- A value in quotes is always treated as a string —
@d1="with spaces"
,@trueString="true"
,@numStr="123"
- All quote styles
[`'"]
are ok —@dq="c" @bt=`b` @sq='a'
- Escaped quotes matching the wrapping quote style are ok —
@ok="escaped\"quote"
- In
"
or`
wrapped values, the string\n
will be converted to an actual newline - Multi-line strings may be wrapped in
(```|"""|"|')
- only available for config item values, not decorators or within function args
Function calls
Section titled “Function calls”Function calls may be used for item values ITEM=fn()
, decorator values # @dec=fn()
, and bare decorator functions # @func()
.
In each case, much of the handling is the same.
- a value must not be wrapped in quotes to be interpreted as a function call
- function names must start with a letter, and can then contain letters, numbers, and underscores
/[a-ZA-Z][a-ZA-Z0-9_]*/
- you can pass no args, a single arg, or multiple args
- you may also pass key value pairs at the end of the list, and they will be combined into a single object at the end of the array
- each value will be interpreted using common value-handling rules (see above)
NO_ARGS=fn()SINGLE_ARG=fn(asdf)MULTIPLE_ARGS=fn(one, "two", three, 123.456)KEY_VALUE_ARGS=fn(key1=v1, key2="v2", key3=true)MIXED_ARGS=fn(item1, item2, key1=v1, key2="v2", key3=true)