
What is an environment variable? A clear, practical guide
- VersionDude
- Tooling
- 6 min read
An environment variable is a key=value pair the operating system hands to a running process, kept outside the source code. What they are, why they matter for config and secrets, how to set and read them, and the good practices that keep secrets out of your repo.
An environment variable is a simple named value - a key and a value, like DATABASE_URL=postgres://localhost/app - that the operating system makes available to a running program. It lives in the process environment rather than inside your source code, so the program can read it at runtime without the value ever being written into the code itself. Every process starts with a set of these variables, inherited from whatever launched it.
Why not just hard-code it?

The point of keeping a value in the environment instead of hard-coding it is separation: the same code can behave differently depending on where it runs, and sensitive values never have to sit in the files you commit. A program asks the environment for a setting when it needs one, and the environment supplies whatever was configured for that particular machine, container or deploy.
Config that changes per environment
The most common use is configuration that changes by environment. Your app might talk to a local database in development and a managed one in production, or run in debug mode on your laptop but not on the server. Instead of editing code for each place, you read a variable - DATABASE_URL, PORT, LOG_LEVEL - and set it to a different value in each environment. The code stays identical; only the environment differs.
- A key=value pair the OS gives to a process
- Config that changes per environment (dev/prod)
- Secrets and API keys, kept out of the code
- Set with export VAR=value; read via process.env / os.environ
- Keep .env in .gitignore - never commit secrets
Secrets and API keys
The second common use is secrets: API keys, database passwords, tokens and other credentials that must never end up in version control. Because environment variables live outside the source tree, they are a standard way to feed these values to a program without committing them. The code reads API_KEY from the environment; the actual key exists only on the machine that runs it, never in the repository.
Variables you already use
You have already met environment variables even if you have not set one. PATH tells the shell which directories to search for commands, HOME points at your home directory, and variables like LANG or TZ describe your locale and timezone. These are set by the operating system and shell for every session, and programs quietly rely on them all the time.
Setting and reading them
Setting and reading them is straightforward. In a Unix-style shell you write export VAR=value to set one for the current session, and read it back as $VAR; on Windows the syntax differs but the idea is the same. In code, you reach the environment through your language: process.env.VAR in Node.js, os.environ["VAR"] in Python, and equivalent calls in most other languages. The program gets a plain string back, which it can then use however it needs.
Typing exports by hand gets tedious, so projects commonly keep their variables in a file - usually named .env - with one KEY=value per line. A small library loads that file into the environment when the program starts: dotenv is the widely used option in the Node.js world, and tools like direnv can load and unload variables automatically as you move between project directories. This keeps the settings for a project together in one place.
Never commit your secrets
That convenience comes with the single most important rule: never commit your secrets. A .env file that holds real keys must be listed in .gitignore so it stays out of version control, and teams usually check in a .env.example with the variable names but blank or dummy values instead. The twelve-factor app methodology, a widely cited guide to building services, makes storing configuration in the environment one of its core principles for exactly this reason.
Pitfalls to watch for
A few pitfalls are worth knowing. Environment variables are strings, so a value like "false" or "0" is still a non-empty string and can trip up truthiness checks. Their scope is the process and whatever it launches, so a variable set in one shell will not appear in another. And because they often carry secrets, be careful not to print the whole environment into logs or error output, where a key could leak. Treat them as plain configuration, keep the secrets out of your repo, and environment variables become one of the simplest, most reliable tools in a developer’s toolkit.



That convenience comes with the single most important rule: never commit your secrets. A .env file that holds real keys must be listed in .gitignore so it stays out of version control, and teams usually check in a .env.example with the variable names but blank or dummy values instead. The twelve-factor app methodology, a widely cited guide to building services, makes storing configuration in the environment one of its core principles for exactly this reason.