How to Set Up Vite + Environment Variables in React 18

Learn how to properly configure environment variables in a Vite + React 18 app with best practices for dev, staging, and production environments.
If you're working with React 18 and Vite, configuring environment variables correctly is essential for separating secrets, toggling feature flags, or managing endpoints across environments. Luckily, Vite offers an ergonomic and type-safe approach.
You don’t want to hardcode API keys or base URLs into your app. Environment variables let you inject values at build time safely and flexibly.
#Prerequisites
- A React 18 project using Vite (v4+ recommended).
- Basic familiarity with
.envfiles.
#Vite Environment Variable Conventions
Vite loads environment variables from .env files based on your current mode. It automatically replaces import.meta.env variables during build time.
Vite recognizes the following files by default:
.env
.env.local
.env.development
.env.production
.env.[mode].local
Only variables prefixed with VITE_ will be exposed to your frontend code.
This is a security feature. Vite will ignore any variable not prefixed with VITE_ to prevent accidental exposure of sensitive keys.
#Example .env File Setup
Here’s a basic .env setup you can use for development:
VITE_API_BASE_URL=https://api.dev.myapp.com
VITE_FEATURE_CHAT=trueYou can override these in .env.production for production builds:
VITE_API_BASE_URL=https://api.myapp.com
VITE_FEATURE_CHAT=false#Accessing Variables in Your Code
You can access the values using import.meta.env:
export const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
export const FEATURE_CHAT_ENABLED = import.meta.env.VITE_FEATURE_CHAT === "true";Vite replaces import.meta.env.* with their actual values at build time — there's no runtime process.env like in Create React App.
#Vite Config File: Custom Modes & Define
You can also pass custom defines or switch modes in vite.config.ts:
import { defineConfig, loadEnv } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), "");
return {
plugins: [react()],
define: {
__APP_VERSION__: JSON.stringify(env.npm_package_version),
},
};
});You can use loadEnv() to read values in vite.config.ts, including ones without VITE_ prefix, since this file runs in Node.
#Custom Modes for Staging
You can add a staging mode easily:
vite build --mode stagingAdd a .env.staging file with staging-specific values:
VITE_API_BASE_URL=https://api.staging.myapp.com#Tips for Deployment
- Never check
.env.localinto version control. - Use a
.env.examplefile to document required variables. - In hosting platforms (like Vercel or Netlify), set your
VITE_vars in the UI or CLI.
Vite builds the environment into your JavaScript bundle. If you want to support runtime configuration (e.g., via window globals or external config JSON), you'll need a custom solution.
#Final Thoughts
Vite’s environment variable system is simple but powerful. Prefix your variables correctly, use different .env.[mode] files for different environments, and leverage import.meta.env directly in your code.
For more advanced configuration patterns, see Vite’s official docs.