.env Formatter
Formats .env files: sort variables, group by prefix, quote values and remove duplicates.
What is .env formatting for?
It does not take long for a .env file to turn into a mess. Keeping it formatted makes it easier to compare environments, review PRs and spot duplicates.
Blank lines and comments (the ones that start with #) stay put. A value with spaces in it ends up wrapped in quotes.
All the processing happens locally.
The .env file and the Twelve-Factor App
The .env file is a plain-text convention for declaring environment variables that a program should read at startup. It was popularized by the original dotenv library for Node.js and later replicated in dozens of ecosystems: python-dotenv, godotenv, Ruby's dotenv gem, Rust's dotenvy, PHP's vlucas/phpdotenv and many others. Docker Compose, GitHub Actions, Vercel, Netlify and Railway all understand the same key/value shape, even if they parse it slightly differently.
The reason this format won is the Twelve-Factor App methodology. Factor III ("Config") states that anything likely to vary between deploys (database URLs, API tokens, hostnames, log levels) must live outside the codebase, in environment variables. The litmus test is brutal: your repository should be safe to open-source at any moment without leaking a single credential. A .env file gives you a language-agnostic, OS-agnostic place to keep those values for local development while real deployments inject the same variables through the platform's secret store.
Twelve-Factor explicitly warns against grouping variables into named buckets such as development, staging or production. Each variable should be independent so the configuration scales linearly as you add deploys, instead of suffering a combinatorial explosion of profiles.
Syntax: KEY=VALUE, comments, quotes and multiline
Every meaningful line is a KEY=VALUE pair. Keys conventionally use UPPER_SNAKE_CASE and must match [A-Za-z_][A-Za-z0-9_]*. Hyphens, accented characters and leading digits are not allowed. There must be no spaces around the equals sign; FOO = bar is parsed by some libraries and rejected by others, so the safe choice is FOO=bar.
# Database
DB_HOST=localhost
DB_PORT=5432
DB_USER=admin
DB_PASSWORD="s3cr3t with spaces"
# Comments start with #
API_BASE_URL=https://api.example.com # inline comment needs a space
LOG_LEVEL=info
Quotes change how values are interpreted. Double quotes enable interpolation and escape sequences (\n, \r, \t, \\): GREETING="Hello\nworld" becomes a two-line string. Single quotes are literal: PATTERN='$VAR' stays as the four characters $VAR. Unquoted values usually allow interpolation but require a space before an inline #, otherwise the # becomes part of the value.
Multiline values (PEM keys, JWKS, JSON blobs) are supported in three ways depending on parser:
# 1. Double-quoted with \n
PRIVATE_KEY="-----BEGIN KEY-----\nMIIEvQI...\n-----END KEY-----\n"
# 2. Real newlines inside double quotes (dotenv >= 15)
PRIVATE_KEY="-----BEGIN KEY-----
MIIEvQI...
-----END KEY-----"
# 3. Backtick block (dotenvx)
PRIVATE_KEY=`-----BEGIN KEY-----
MIIEvQI...
-----END KEY-----`
Loading by platform
- Node.js:
require('dotenv').config()or the nativenode --env-file=.env app.jsflag. - Python:
from dotenv import load_dotenv; load_dotenv(). - Docker Compose: an
.envnext todocker-compose.ymlis read automatically for variable substitution; per-service useenv_file:. - GitHub Actions: store secrets in repository settings, then expose them as
env:blocks in the workflow. - Vercel / Netlify / Railway / Fly.io: paste the contents of your
.envthrough the dashboard or CLI; the platform injects them at build and runtime. - Kubernetes: convert to a
ConfigMap(non-sensitive) orSecret(sensitive) and mount as env vars on the pod.
Security: never commit, always ignore
A .env file with real credentials must never reach version control. Always add it to .gitignore from day one and commit a sanitized .env.example with placeholder values that documents which variables the app expects. According to GitGuardian's State of Secrets Sprawl, millions of credentials are leaked in public GitHub commits every year, and a leaked .env is one of the most common vectors.
For teams, plain .env files do not scale: there is no audit log, no rotation, no per-developer access control. The mature alternatives are:
- dotenv-vault / dotenvx — encrypts the
.envat rest with AES-GCM; you commit the encrypted blob and a single decryption key lives outside the repo. - SOPS (Mozilla) — encrypts YAML/JSON/ENV files using AWS KMS, GCP KMS, Azure Key Vault, age or PGP. Plays well with GitOps.
- HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager, Azure Key Vault, Doppler, Infisical — central vaults with audit logging, rotation and fine-grained IAM.
Best practices
- Use consistent
UPPER_SNAKE_CASEnames; group by prefix (DB_*,STRIPE_*,AWS_*). - Validate variables at startup with a schema (Zod, Joi, Pydantic, envalid) so the app crashes loudly when a required key is missing or malformed, instead of failing silently in production.
- Keep secrets out of build artifacts: never bake them into Docker images or front-end bundles; prefer runtime injection.
- Rotate credentials periodically and on every offboarding.
- Document every variable in
.env.examplewith a one-line comment.
Common mistakes
- Spaces around
=(FOO = bar) — works in some parsers, fails in others. - Missing closing quote in a multiline value — everything after is swallowed.
- UTF-8 BOM at the start of the file — the first key becomes
KEYand is never matched. - Hash inside an unquoted value (
COLOR=#fff) — the parser treats it as a comment; quote the value. - Expecting interpolation in single quotes (
URL='https://$HOST') — it stays literal. - Duplicate keys — only the last (or the first, depending on parser) wins.
FAQ
Is there an official spec for .env? No. The format is a de-facto convention shared across implementations with small differences in quoting, escaping and interpolation. Always test with the parser you actually ship.
Can I have multiple .env files? Yes — common patterns are .env, .env.local, .env.development, .env.production. Frameworks like Next.js, Vite and Rails load them in a documented order; check your tool's manual.
Should I commit .env.example? Yes. It documents required variables without exposing values and lets new contributors copy it to .env and fill in their own secrets.
Are environment variables really safe? They are safer than hard-coded constants but still readable by every process running under the same user. For production secrets, prefer a vault with runtime injection so plaintext never lands on disk.
Does the formatter modify my values? No. It only normalizes whitespace, sorts or groups keys, optionally quotes values that contain spaces and removes duplicates. The values themselves are preserved byte for byte.
Organise your .env file
The .env file, where a project's environment variables live, tends to turn into a mess: variables in any order, values with no standard. This tool tidies it up automatically, leaving the file more readable and easier to maintain.
It puts the variables in alphabetical order, can group them by prefix (pulling together all the DB_ or AWS_ ones, say), wraps the values that need it in quotes and drops the duplicates. What's left is a consistent .env where finding each key is simple. Good for reviewing a project or lining up configuration across environments.
Everything is processed in the browser, so the file (which normally holds secrets and credentials) never leaves your device. Sensitive configuration calls for that care.
Related Tools
JSON Flatten / Unflatten
Flatten a nested JSON into dot-notation keys (e.g. user.address.city) and rebuild the reverse path. Useful to export to CSV, generate .env files or compare configs. Everything in your browser.
tsconfig Strict Generator
Generate a strict tsconfig.json.
Webpack Config Generator
Generate a minimal webpack.config.js.