Skip to content

React Tutorial Data and APIs

Environment Variables in a React Vite Project

Lesson 99 of 156 3 min read By Deepak Paswan Updated Oct 10, 2026

Full-project lesson · needs Node.js, npm and real project files, so it does not run in the in-page playground.

Different environments need different settings: your local machine talks to a test API, production to the real one. Environment variables keep those settings out of your code, so you do not edit source files to deploy.

Vite and .env files

Vite reads environment variables from files in the project root:

FileLoaded
.envAlways
.env.localAlways, ignored by Git (the template’s .gitignore has *.local)
.env.developmentOnly with npm run dev (mode development)
.env.productionOnly with npm run build (mode production)
.env.[mode].localA specific mode, local only

More specific files override less specific ones.

The VITE_ prefix

Only variables that start with VITE_ are exposed to your client code. Everything else stays in Node and is invisible to the browser. This protects you from leaking something by accident, but it also means that anything that is exposed is public; see the warning below.

Create a file named .env in the project root:

.env
PLAIN
VITE_API_URL=https://api.example.com
VITE_APP_NAME=Learning Shop

Read the values in code with import.meta.env:

src/App.jsx
JSX
function App() {
  return (
    <p>
      {import.meta.env.VITE_APP_NAME} talks to {import.meta.env.VITE_API_URL}
    </p>
  )
}

export default App

This was built with Vite and checked in a browser: the page shows the values from .env, and the built JavaScript file contains the literal text https://api.example.com. That second fact matters; see the warning.

Built-in values

Vite also provides these automatically:

ValueMeaning
import.meta.env.MODE"development" or "production" (or your custom mode)
import.meta.env.DEVtrue in dev
import.meta.env.PRODtrue in a production build
import.meta.env.BASE_URLThe base path the app is served from
App.jsx
JSX
if (import.meta.env.DEV) {
  console.log('Running in development')
}

Values are replaced at build time

During npm run build, Vite replaces each import.meta.env.VITE_X with the literal value. The built files contain the text. To change a value you must rebuild. You cannot change it by editing the server’s environment after the build, unless your app loads a config file at run time.

dangerous
Everything with the VITE_ prefix is public
Anyone can open the browser’s developer tools or read your JavaScript file and see the values. Never put passwords, private API keys, tokens or database URLs in a VITE_ variable. Use environment variables for configuration (an API base URL, a public analytics id), not for secrets. The next lessons explain what to do with secrets: API Security Fundamentals and Why Secret Keys Must Not Be Exposed.

Do not commit secrets, even for public values

Commit a template file such as .env.example that lists the names with fake or empty values, and keep real local values in .env.local. For public configuration, committing .env is fine, but the habit of keeping local overrides in .env.local protects you when someone adds a sensitive value later.

Modes

You can run Vite in any mode and load matching files:

terminal
BASH
npm run dev                          # mode: development
npm run build                        # mode: production
npx vite build --mode staging        # loads .env.staging

TypeScript

Declare your variables so import.meta.env is typed. The Vite TypeScript template includes a vite-env.d.ts file where you extend ImportMetaEnv:

script.ts
TS
interface ImportMetaEnv {
  readonly VITE_API_URL: string
  readonly VITE_APP_NAME: string
}

Common mistakes

  • Forgetting the VITE_ prefix. The value is undefined in the browser.
  • Using process.env. That is Node syntax. In Vite, use import.meta.env.
  • Editing .env while the dev server runs. Restart the server to pick up changes.
  • Expecting runtime configuration. The values are fixed when you build.
  • Putting secrets in VITE_ variables, the most serious mistake.

Key points

  • Put configuration in .env files and read it with import.meta.env.VITE_NAME.
  • Only VITE_-prefixed variables reach the browser, and they are visible to everyone.
  • Values are inlined at build time, so rebuild after changing them.