An environment variable is a named value that lives in your operating system and gets handed to any program when it starts. Think of it as a sticky note the OS keeps on hand: a program can ask for DATABASE_URL or API_KEY and the system reads the value off the note. They exist so that the same code can run on your laptop, a teammate machine, and a production server while still behaving differently in each place. That is the whole point, and it is simpler than the tooling around it suggests.
How environment variables work
Every running process has its own copy of an environment: a list of NAME=value pairs inherited from whatever launched it. When you open a terminal, the shell hands its environment to every command you run. When a web server boots, the system or container runtime hands it the variables you configured.
The value is always a string. There are no numbers, booleans, or lists at the OS level; if your program needs a number, it reads the string and converts it. Names are case-sensitive on Linux and macOS and conventionally written in UPPER_SNAKE_CASE.
The key property is inheritance: a child process gets a copy of the parent environment. Changing a variable inside a program does not change the parent shell, which is why a script cannot permanently alter the terminal that ran it.
Why they matter
The core idea is separating configuration from code. The same application should not be edited just because it moves from your machine to a server. Environment variables let one codebase adapt to its surroundings.
| Use case |
Example variable |
Why an env var |
| Secrets |
STRIPE_SECRET_KEY |
Keeps keys out of source control |
| Connection info |
DATABASE_URL |
Differs per environment |
| Feature flags |
ENABLE_BETA=true |
Toggle behavior without redeploying code |
| Runtime mode |
NODE_ENV=production |
Switches logging, caching, error detail |
| Ports and hosts |
PORT=8080 |
Hosting platforms set these for you |
This pattern is part of what the "twelve-factor app" guidelines popularized, and in 2026 it is the default expectation for any deployable service.
How to set one
In a Linux or macOS shell, export sets a variable for the current session:
// set for this terminal session only
export API_KEY="abc123"
echo $API_KEY
To make it persist, add the line to your shell profile such as ~/.zshrc or ~/.bashrc. On Windows PowerShell:
$Env:API_KEY = "abc123"
In code, you read them rather than set them:
import os
api_key = os.environ["API_KEY"] // raises if missing
debug = os.environ.get("DEBUG", "false") // default fallback
// Node reads process.env; values are always strings
const key = process.env.API_KEY;
const port = Number(process.env.PORT ?? 3000);
The .env file pattern
A .env file lists variables in one place so you do not retype export lines. A loader library reads the file at startup. It is a developer convenience, not an OS feature.
// .env -- never commit this file
DATABASE_URL=postgres://localhost/dev
API_KEY=abc123
Tools like python-dotenv, the dotenv npm package, or built-in support in many frameworks load these into the process environment. Always add .env to .gitignore and commit a .env.example with blank values so teammates know which keys to fill in.
Common mistakes
Committing secrets. A .env file in a public repository is the classic way keys leak. Rotate any key the moment it touches git history.
Putting secrets in frontend code. Anything in browser JavaScript is visible to users, a recurring theme in frontend development. A build tool can inline PUBLIC_ variables, so never prefix a real secret that way.
Assuming a variable exists. Read with a clear error or a sensible default; a missing variable crashing at request time is worse than failing loudly at boot.
Storing structured data. Values are strings. Do not stuff JSON blobs in; use a config file for anything complex.
What to skip
- Custom config formats — environment variables plus a small config file cover almost every case.
- Sharing one
.env across the whole team by email — use a secrets manager for anything production.
- Reinventing secret encryption — your hosting platform or a dedicated vault already does this.
FAQ
What is the difference between an environment variable and a config file?
A config file is read by your application directly and usually lives in the repo. An environment variable is supplied by the OS or hosting platform at runtime, which makes it the better home for secrets and per-environment values.
Are environment variables secure?
They keep secrets out of source code, which is a real improvement, but they are readable by the process and by anyone with access to the machine. For sensitive production keys, use a dedicated secrets manager.
Why does my variable disappear when I open a new terminal?
A variable set with export lives only in that session. To persist it, add the line to your shell profile or set it through your OS or hosting platform.
Do I need to restart my app after changing a variable?
Yes. A process reads its environment when it starts, so changes take effect only after a restart.
Where to go next
See what is an API key in 2026, what is a config file and how secrets work, and how to secure your home wifi in 2026.