Environment Variables Explained: Keeping Secrets Out of Code
Learn what environment variables are and why every developer needs them. This guide covers how to use .env files, os.environ in Python, process.env in Node.js, and best practices.
One of the most common beginner mistakes is hardcoding API keys, database passwords, and secrets directly in code — and then accidentally pushing them to GitHub. Environment variables are the solution. They keep sensitive configuration out of your codebase entirely.
What Are Environment Variables?
Environment variables are key-value pairs stored outside your code, in the environment where your application runs. Your code reads them at runtime instead of having the values baked in.
# BAD — secret is in your code
DATABASE_URL = "postgresql://admin:supersecret@prod-server/mydb"
# GOOD — value comes from the environment
import os
DATABASE_URL = os.environ.get("DATABASE_URL")
Using .env Files in Development
In local development, store variables in a .env file:
# .env
DATABASE_URL=postgresql://localhost/myapp
SECRET_KEY=my-local-dev-secret
STRIPE_API_KEY=sk_test_abc123
DEBUG=true
Critical: add .env to your .gitignore — this file should never be committed:
echo ".env" >> .gitignore
Reading .env Files in Python
Use the python-dotenv library:
from dotenv import load_dotenv
import os
load_dotenv() # Reads .env into os.environ
db_url = os.environ.get("DATABASE_URL")
secret = os.environ.get("SECRET_KEY")
debug = os.environ.get("DEBUG", "false").lower() == "true"
Reading .env Files in JavaScript / Node.js
// Install: npm install dotenv
require("dotenv").config();
const dbUrl = process.env.DATABASE_URL;
const apiKey = process.env.STRIPE_API_KEY;
In Production
On hosting platforms (Vercel, Railway, Heroku), you set environment variables through their dashboard or CLI — no .env file needed. The platform injects them into your app’s runtime environment.
What to Store in Environment Variables
- Database connection strings
- API keys and secrets
- JWT secret keys
- Third-party service credentials
- Feature flags (
DEBUG=true) - Environment-specific URLs
Conclusion
Environment variables are a simple, universal pattern for keeping secrets out of code. Add .env to .gitignore, use a library to load them locally, and configure them through your platform dashboard in production. This one habit prevents a whole category of security incidents.
Read next: Python Virtual Environments
External resource: The Twelve-Factor App — Config
Related Articles
CSS Flexbox in Plain English: A Beginner's Guide
Learn CSS Flexbox with simple, visual explanations. This guide covers display flex, justify-content, align-items, flex-wrap, and practical layouts every developer needs to know.
Docker for Backend Developers: A Practical Introduction
Learn how Docker works, why backend developers need it, and how to containerize your first Python or Go application in under 30 minutes.
Containerising a Backend Service: From Docker to Kubernetes
A practical walkthrough of containerising a Python backend service with Docker, deploying it to Kubernetes on ECS, and the production gaps that only show up once real traffic hits.