← Back to React Course | Chapter 14: Performance & Production Deployment | Lesson 9 of 13

Environment Variables in React

Environment variables are like different settings sheets for the same recipe — one sheet for practicing at home, a different one for cooking at the real restaurant.

Defining and Reading Environment Variables

A .env file at your project root defines key-value pairs your build tool reads and makes available to your code. In Vite, client-exposed variables must be prefixed with VITE_, and are accessed via import.meta.env.VITE_SOMETHING in your code.

Note: Restart the dev server after adding or changing variables in .env — most build tools only read the file at startup, not live.

Warning: A variable without the required prefix (VITE_ in Vite) is silently NOT exposed to client code, even though it's defined in the .env file.

Example: Defining and Reading Environment Variables

markup
// Run in your local React project (npm install required)
// .env
VITE_API_URL=https://api.example.com

// In your code:
const apiUrl = import.meta.env.VITE_API_URL;
fetch(apiUrl + '/users');

Why Client-Side Variables Are Never Truly Secret

Anything bundled into your client-side JavaScript, including environment variables exposed this way, ends up downloadable and readable by anyone who opens browser devtools and inspects the bundle. Real secrets (API keys with write access, database credentials) must stay server-side, never in a client-exposed env variable.

Note: A useful test: if leaking this value publicly would be a problem, it doesn't belong in a VITE_/REACT_APP_-prefixed variable.

Warning: Putting a genuinely secret API key in a VITE_-prefixed variable effectively publishes that key to anyone who visits your site and opens devtools.

Different Values per Environment

Separate .env files (like .env.development and .env.production) let the same codebase automatically use different values — like a local API URL during development and the real production API URL when deployed — without changing any actual code.

Note: Most build tools automatically pick the right .env file based on the current mode (development vs. production) without extra configuration.

Warning: Accidentally committing a .env.production file with real secrets to a public repository exposes them — use .gitignore for any file containing sensitive values.

Example: Different Values per Environment

markup
// Run in your local React project (npm install required)
// .env.development
VITE_API_URL=http://localhost:4000

// .env.production
VITE_API_URL=https://api.myrealapp.com

// Same code works correctly against both, automatically:
fetch(import.meta.env.VITE_API_URL + '/users');
Common Mistakes
  1. Putting genuinely secret values (API secret keys) in a client-side environment variable — anything bundled into client JS is visible to anyone who opens devtools.
  2. Forgetting the required prefix (like VITE_ or REACT_APP_) that the build tool needs to actually expose a variable to client code.
  3. Not restarting the dev server after changing a .env file, missing the update since env vars are typically read at build/start time.
Chapter Summary
  • Environment variables let the same code behave differently in development vs. production (like pointing at different API URLs).
  • Client-exposed variables need a specific prefix (VITE_ for Vite, REACT_APP_ for Create React App) to actually reach the browser bundle.
  • Any variable exposed to client-side code is publicly visible — never put real secrets there.
  • Variables are typically defined in .env files, with different files for different environments (.env.production, .env.development).
Browser Support

Build-tool feature (Vite's import.meta.env or Create React App's process.env); no specific React version requirement.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.