Optional Keys

Mark a key @optional when your code copes with it being unset. dotenv-diff then stops reporting it as missing, and you are free to leave it out of your .env.

Syntax

Add the annotation directly above the key in .env.example.

.env.example
# Cache layer - falls back to an in-memory store when unset
# @optional
REDIS_URL=

The same annotation styles as @expire are supported.

.env.example
# @optional
KEY_A=

// @optional
KEY_B=

@optional
KEY_C=

# optional
KEY_D=

Rules

  • The @ is optional — # optional also works.
  • The annotation applies to the next env key only.
  • A comment line between the annotation and the key is fine — the annotation still attaches to the key below it.
  • A blank line ends the block, so the annotation cannot leak onto an unrelated key further down.
  • The annotation must be alone on its line. # @optional, falls back to memory is read as an ordinary comment and has no effect — put the prose on its own line above it.

Behavior

Optional means "you don't have to set this", so both ways of not setting it are accepted:

  • Absent from .env: a required key is reported as missing, an @optional key is not.
  • Present but empty in --compare: a required key is reported as empty, an @optional key is not.

Nothing else changes. An optional key is still checked for duplicates, secrets and naming, and is still reported as unused when nothing in your codebase reads it.

No Flag Needed

@optional is always active — there is nothing to enable. Writing the annotation can only remove a warning, never add one, so adopting it cannot break an existing pipeline.

Note that the annotation is not documentation. A key with only # @optional above it still explains nothing about what it is for, so keep a real comment above the annotation.

See also