What Is an Environment Variable? .env Files Explained
Environment variables are how an app gets its settings and secrets — database passwords, API keys, the site's URL — without writing them into the code. What they are, how .env files work, why they must never reach GitHub, and the prefix that quietly makes a 'secret' public.
Your app needs some information that shouldn't be written into its code: the password to your database, your Stripe secret key, your email service's API key, the address of your live site. The standard way to give an app that information is environment variables.
What an environment variable is
An environment variable is a named setting that lives outside your code, which your app reads when it runs. For example:
DATABASE_URL=postgres://app:[email protected]:5432/app
STRIPE_SECRET_KEY=sk_live_...
APP_URL=https://yourapp.com
And in the code, instead of writing the secret itself:
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY)
The code says "use whatever STRIPE_SECRET_KEY is." The actual value is provided separately.
Why not just put the value in the code?
Three reasons:
- Secrets in code end up everywhere. In git history, on GitHub, in screenshots, in AI chats. Once a key is in your code, it's very hard to keep it secret.
- Different places need different values. Your laptop should use a test database and Stripe's test keys; the live site needs real ones. Same code, different settings.
- Changing a setting shouldn't need a code change. Rotating a leaked key should be a settings update, not a redeploy of new code.
.env files: environment variables on your computer
On your own machine, the usual way to set them is a file named .env in your project folder:
# .env — never commit this file
DATABASE_URL=postgres://dev:dev@localhost:5432/myapp_dev
STRIPE_SECRET_KEY=sk_test_51Ab...
APP_URL=http://localhost:3000
Your framework reads this file when the app starts. Most frameworks (Next.js, Vite, and others) do it automatically; some projects use a small library called dotenv.
The most important rule: .env never goes to GitHub
Make sure .env is listed in your project's .gitignore file, which tells git not to track it:
# .gitignore
.env
.env.local
Check with git status — .env should never appear in the list of files to commit.
Instead, commit a .env.example file with the names of every variable and fake or blank values, so anyone (including you in six months) knows what the app needs:
# .env.example
DATABASE_URL=postgres://user:password@localhost:5432/myapp_dev
STRIPE_SECRET_KEY=sk_test_replace_me
APP_URL=http://localhost:3000
If a real secret ever does get pushed to GitHub: get a new key immediately from the service and delete the old one. Removing it from the code afterwards doesn't help — it's in the history, and bots scan GitHub for leaked keys within minutes.
On your live site: the host's settings
Your .env file stays on your computer. Your live app gets its environment variables from your hosting provider's settings — there's always a page for this, often called "Environment Variables," "Secrets," or "Config."
Forgetting to copy them there is the number-one reason apps work locally but crash when deployed. Go down your .env.example line by line and set each one with its production value. (Why Does My App Work Locally but Not in Production?)
Most hosts only read variables when the app starts or builds, so redeploy after changing them.
The prefix trap: VITE_, NEXT_PUBLIC_, REACT_APP_
This one catches a lot of AI-built apps. Frontend frameworks have a special prefix for variables that should be available in the browser:
- Vite:
VITE_ - Next.js:
NEXT_PUBLIC_ - Create React App:
REACT_APP_ - Expo:
EXPO_PUBLIC_
Any variable with that prefix is copied into the JavaScript that every visitor downloads. It is public. Anyone can read it.
So:
- ✅
NEXT_PUBLIC_SITE_NAME=My App— fine, it's meant to be public. - ✅
VITE_SUPABASE_ANON_KEY=...— fine, it's designed to be public (as long as your database security rules are right). - ❌
VITE_OPENAI_API_KEY=...— leaked. Anyone can take it and run up your bill. - ❌
NEXT_PUBLIC_STRIPE_SECRET_KEY=...— leaked. Anyone can use your Stripe account.
AI tools sometimes add these prefixes to make an error go away. If a variable is a secret, it must not have the prefix — and the code that uses it must run on the server. How to Keep API Keys Out of an AI-Built App explains how to fix it properly.
A few more tips
- Names are usually UPPER_CASE_WITH_UNDERSCORES. Convention, not a rule.
- No spaces around
=in.envfiles. Quote values that contain spaces. - Restart your dev server after changing
.env— it's read at startup. - Don't paste your
.envinto AI chats or screenshots. Share.env.exampleinstead. - Use separate keys for development and production, so a leaked test key can't touch real data or money.
The summary
- Environment variables keep settings and secrets out of your code.
- Locally, they live in
.env— which must be in.gitignore. - Commit
.env.examplewith names and fake values. - On your host, set them in the hosting settings, then redeploy.
- Anything with
VITE_/NEXT_PUBLIC_/REACT_APP_is public — never put secrets there.
EasySpawn stores your environment variables with the workspace, so they persist between sessions and reach your app on the server — where secrets belong. See how it works for AI-built apps or join the waitlist.
Related: Frontend vs Backend · What Is an API? · What Is .gitignore? · Secrets Management Beyond .env Files
Keep reading
What Is a JWT? JSON Web Tokens Explained Simply
Supabase, Firebase, Auth0, and Clerk all hand your app JWTs. What a JSON Web Token is, its three parts, why anyone can read it but nobody can forge it, how apps use it for login, and the mistakes AI-generated code makes with tokens.
GDPR Basics for App Builders: What a Small App Actually Needs
If anyone in the EU or UK uses your app, GDPR probably applies. What personal data is, the principles in plain English, lawful bases, the rights users have (access, deletion), what to do about third-party services and data breaches, and a practical checklist for a small app. Not legal advice.