Hard-coding a database password or API key into your source is one of the most common — and most dangerous — habits in software. Environment variables are the standard answer: a clean way to separate configuration from code, keep secrets out of version control, and run the same code across development, staging and production.
Why config belongs in the environment
The same application should run unchanged whether it is on your laptop or a production server — only its configuration differs. Storing that configuration in environment variables, rather than in code, achieves exactly that. It is a core principle of building portable, deployable software: strict separation of config from code.
How .env files work
In development, a .env file holds key-value pairs that a library loads into the environment when the app starts. It keeps local configuration convenient without baking values into code. Crucially, the .env file must never be committed to version control — add it to .gitignore and commit a .env.example with blank or dummy values to document what is needed.
Keeping secrets safe
- Never commit real secrets — use .gitignore for .env files.
- Provide a .env.example so others know which variables to set.
- In production, set variables through your host’s configuration or a secrets manager, not a file in the repo.
- Rotate any secret that has ever been committed, even briefly — assume it is compromised.
Generating good secret values
Many environment variables are secrets — API keys, session keys, signing secrets. These should be long and random, not memorable strings. Generate them with a cryptographically secure source so they cannot be guessed, and use a different value in each environment.