.env File Syntax Reference

.env variable syntax, quoting rules, comment handling and shell expansion notes.

Reference and live linter for .env file syntax: variable assignment, single and double quoting, comments, multiline values, the export prefix and $VAR interpolation, with per-line validation. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

Do .env values need quotes?

Only when they contain spaces, special characters or you want to control interpolation. Unquoted values run to the end of the line (or an inline comment) with surrounding whitespace trimmed. Double quotes preserve spaces and allow escape sequences and $VAR interpolation; single quotes are fully literal.

The .env file format

A .env file stores configuration as one KEY=value assignment per line, loaded into a process’s environment at startup. The format looks trivial, but quoting, comments and interpolation differ subtly between loaders. This reference documents the rules and includes a live linter that classifies every line you paste.

How it works

Each non-blank, non-comment line is split at the first = into a key and a value. The key should be UPPER_SNAKE_CASE and may not start with a digit:

# a comment line
API_KEY="sk_live_123"      # double quotes preserve and can interpolate
SECRET='raw$value'          # single quotes are fully literal
DB_URL=$HOST/db             # $VAR expands in many loaders
export PORT=3000            # export prefix is stripped by the loader
EMPTY=                      # assigns an empty string

The linter applies exactly this logic: blank and # lines are ignored, a valid key/value reports whether the value is quoted, empty or unquoted, and a line with no = (and not a comment) is flagged as an error.

Tips and notes

  • Single-quote any secret containing $ so it is not treated as interpolation.
  • Behaviour varies across Node dotenv, python-dotenv and docker-compose — test in your loader.
  • Never commit a real .env; ship a .env.example with placeholder values instead.
  • Keep keys UPPER_SNAKE_CASE and avoid spaces around = for the widest compatibility.

Quoting rules compared

The three quoting modes behave differently in ways that catch developers by surprise:

No quotes — the value runs from after = to the end of the line. Leading and trailing whitespace is typically trimmed by the loader. A # character anywhere in an unquoted value starts an inline comment in most loaders, so API_KEY=abc#123 gives you abc, not abc#123. Use quotes if your value contains a hash.

Double quotes — spaces and special characters are preserved within the quotes. Most loaders support \n, \t, and other backslash escapes in double-quoted values, and expand $VAR or ${VAR} references. This is the right choice for multi-word values, values with internal spaces, or values that reference other variables.

Single quotes — the value is completely literal. No escape sequences are processed, no variable references are expanded, and no characters have special meaning. A single-quoted value that contains a dollar sign, backslash, or hash is stored exactly as written. This is the safest choice for secrets, API keys, and any value that might happen to contain characters that other modes treat specially.

Loader differences to be aware of

.env files have no single canonical specification. Different tools implement subtly different rules:

BehaviourNode.js dotenvPython python-dotenvDocker Compose
export prefix strippedYesYesYes
Inline comments on unquoted valuesYesYesYes
\n in double-quoted valuesYesYesYes
$VAR interpolationOptional (flag)Optional (flag)Yes (by default)
Multiline double-quoted valuesYesYesLimited

The biggest risk is $VAR interpolation. If you use Docker Compose and your .env contains a value like PASSWORD=abc$def, Docker Compose will try to expand $def as an environment variable and may silently produce PASSWORD=abc if $def is not defined. Always use single quotes for literal dollar signs in a Docker Compose environment.

Security practices

A .env file containing real credentials is a security risk if it reaches version control, an image layer, or a log file. Follow these practices:

  • Add .env to .gitignore and verify it is not tracked: git check-ignore -v .env.
  • Commit only a .env.example with placeholder values: API_KEY=your_key_here.
  • In Docker images, never COPY .env . — use runtime environment injection from your orchestrator instead.
  • In CI/CD, inject secrets as masked environment variables from your secrets manager, not from a committed .env file.
  • Rotate any credential that you suspect was exposed in a commit history. git log does not forget, even after a git rm.