Root @decorators
Root decorators appear in the header section of a .env file - which is any comment block(s) at the beginning of the file, before the first config item. Usually root decorators are used only in your .env.schema file.
# This is the header, it can contain root decorators# @defaultSensitive=false @defaultRequired=infer# @generateTypes(lang=ts, path=./env.d.ts)More details of the minutiae of decorator handling can be found in the @env-spec reference.
Built-in root decorators
Section titled “Built-in root decorators”These are the root decorators that are built into Varlock. Plugins may introduce more.
@currentEnv
Section titled “@currentEnv”Value type: ref() (usually written as $ITEM_NAME)
Sets the current environment value, which will be used when determining if environment-specific .env files will be loaded (e.g. .env.production),
and also may affect other dynamic behaviour in your schema, such as the forEnv() function. We refer to the name of this item as your environment flag.
- It must be set to a simple reference to a single config item (e.g.
$APP_ENV). - This decorator should only be set in your
.env.schemafile. - The referenced item must be defined within the same file.
- This will override the
--envCLI flag if it is set. - We do not recommend using
NODE_ENVas your environment flag, as it has other implications, and is often set out of your control.
See environments guide for more info.
# @currentEnv=$APP_ENV# ---# @type=enum(dev, preview, prod, test)APP_ENV=dev@envFlag (deprecated)
Section titled “@envFlag (deprecated)”Value type: string (must be a valid item name within same file)
Sets the current environment flag by name.
⚠️ Deprecated at v0.1 - use @currentEnv instead.
@envFlag=APP_ENV -> @currentEnv=$APP_ENV
@defaultRequired
Section titled “@defaultRequired”Value type: boolean | "infer"
Sets the default behavior of each item being required. Only applied to items that have a definition within the same file. Can be overridden on individual items using @required/@optional.
infer(default): Items with a value set in the same file will be required; items with an empty string or no value are optional.true: All items are required unless marked optional.false: All items are optional unless marked required.
# @defaultRequired=infer# ---
FOO=bar # required (static value)BAR=fnCall() # required (function value)BAZ= # optional (no value)QUX='' # optional (empty string)
# @optionalOPTIONAL_ITEM=foo # optional (explicit)
# @requiredREQUIRED_ITEM= # required (explicit)@defaultSensitive
Section titled “@defaultSensitive”Value type: boolean | inferFromPrefix(PREFIX)
Sets the default state of each item being treated as sensitive. Only applied to items that have a definition within the same file. Can be overridden on individual items using @sensitive.
true(default): All items are sensitive unless marked otherwise.false: All items are not sensitive unless marked otherwise.inferFromPrefix(PREFIX): Item is marked not sensitive if key starts with the givenPREFIX; all others are sensitive. Useful for marking e.g.PUBLIC_keys as non-sensitive by default.
# @defaultSensitive=inferFromPrefix(PUBLIC_)# ---
PUBLIC_FOO= # not sensitive (due to matching prefix)OTHER_FOO= # sensitive (default when prefix does not match)
# @sensitivePUBLIC_BAR= # sensitive (explicit decorator overrides prefix)# @sensitive=falseOTHER_BAR= # not sensitive (explicit)@disable
Section titled “@disable”Value type: boolean
If true, disables loading the file - meaning no items or plugins are loaded from it. Useful for temporarily or conditionally disabling a .env file.
💡 The forEnv() function can disable an explicitly imported file based on the current environment.
# @disable # (shorthand for @disable=true)## @plugin(@varlock/x-plugin) # will not be loaded# ---FOO=bar # will be ignored@import()
Section titled “@import()”Arg types: [ path: string, ...keys?: string[] ]
Named args: enabled?: boolean, allowMissing?: boolean
Imports other .env file(s) - useful for sharing config across monorepos and splitting up large schemas. Can be called multiple times.
You may import a specific file, or a directory of files - automatically loading all .env.* files appropriately according to the current environment flag.
The optional enabled parameter allows conditional imports based on boolean expressions. It defaults to true if not specified.
The optional allowMissing parameter makes the import optional - if set to true, the import will be silently skipped if the file or directory doesn’t exist instead of causing a loading error. It defaults to false if not specified.
See the imports guide for more details and advanced usage.
# @import(./.env.imported) # import a specific file# @import(./.env.other, KEY1, KEY2) # import specific keys# @import(../shared-env/) # import a directory# @import(~/.env.shared) # import from home directory# @import(./.env.dev, enabled=eq($ENV, "dev")) # conditional import# @import(./.env.local, allowMissing=true) # optional import (no error if missing)# ---
# this definition is merged with any found in imports, but this one has more precedenceIMPORTED_ITEM=overriden-value@setValuesBulk()
Section titled “@setValuesBulk()”Arg types: [ data: string ]
Named args: format?: "json" | "env", createMissing?: boolean, enabled?: boolean
Injects multiple config values at once from an external data source. The first argument is a resolver that produces a string (e.g., exec() calling a secrets manager), which is parsed and injected as definitions within the file containing the decorator.
Bulk values participate in the normal file override chain — process.env still overrides everything, higher-precedence files (.env.local, .env.production, etc.) override bulk values, and bulk values override schema-defined defaults in the same file. You control precedence by choosing which file to put @setValuesBulk in.
Options:
format: How to parse the data string.jsonexpects a flat JSON object,envexpects.envfile format. If not specified, auto-detected by checking if the string starts with{.createMissing: Iftrue, keys in the bulk data that don’t already exist in your schema will be created as new config items. Defaults tofalse(unknown keys are silently skipped).enabled: Iffalse, the bulk data resolver is skipped entirely. Accepts any boolean expression, including dynamic references to other config items. Defaults totrue.
Can be called multiple times — later calls overwrite earlier ones for the same keys.
# Inject secrets from a vault as JSON# @setValuesBulk(exec("vault kv get -format=json secret/myapp"), format=json)# ---API_KEY=DB_PASSWORD=# Inject from a secrets file as .env format# @setValuesBulk(exec("cat /run/secrets/env"), format=env)# ---API_KEY=DB_PASSWORD=# Create items not already in the schema# @setValuesBulk(exec("vault kv get -format=json secret/myapp"), format=json, createMissing=true)# Only fetch from the vault in non-production environments# @setValuesBulk(exec("vault kv get -format=json secret/dev"), format=json, enabled=eq($APP_ENV, "dev"))# ---API_KEY=APP_ENV=dev@plugin()
Section titled “@plugin()”Arg types: [ identifier: string ]
Loads a plugin, which can register new root decorators, item decorators, and resolver functions. Can be called multiple times.
See plugins guide for more details.
# @plugin(@varlock/1password-plugin)# @initOp(allowAppAuth=true) # new root decorator# ---# @type=opServiceAccountToken # new data typeOP_TOKEN=# @sensitiveXYZ_API_KEY=op(op://api-prod/xyz/api-key) # new resolver@generateTypes()
Section titled “@generateTypes()”Arg types (key/value):
lang: Language to generate types for (currently onlyts/ TypeScript is supported, with more languages planned)path: Relative filepath to output generated type fileauto: Controls whether types are generated automatically on every load (defaults totrue). Set tofalseto disable automatic generation and instead runvarlock typegenexplicitly.executeWhenImported: overrides the default behaviour of not executing when the containing file is imported (defaults tofalse)
Triggers type generation based on your schema. Can be called multiple times.
# @generateTypes(lang=ts, path=./env.d.ts)@redactLogs
Section titled “@redactLogs”Value type: boolean
Controls whether sensitive config values are automatically redacted from console output. When enabled, any sensitive values will be replaced with ▒▒▒▒▒ in logs.
Only applies in JavaScript based projects where varlock runtime code is imported.
true(default): Console logs are automatically redactedfalse: Console logs are not redacted (useful for debugging)
# @redactLogs=false# ---SECRET_KEY=my-secret-value # @sensitiveconsole.log(process.env.SECRET_KEY)// This will log "my▒▒▒▒▒" instead of "my-secret-value" when @redactLogs=true@preventLeaks
Section titled “@preventLeaks”Value type: boolean
Controls whether leak prevention is enabled. When enabled, varlock will scan outgoing HTTP responses to detect if sensitive values are being leaked.
Only applies in JavaScript based projects where varlock runtime code is imported.
Options:
true(default): Leak detection is enabledfalse: Leak detection is disabled (useful for debugging)
# @preventLeaks=false# ---SECRET_KEY=my-secret-value # @sensitive
a sample leak detection warning in an Astro project