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
.env
files.
#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=true
You 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 staging
Add a .env.staging
file with staging-specific values:
VITE_API_BASE_URL=https://api.staging.myapp.com
#Tips for Deployment
- Never check
.env.local
into version control. - Use a
.env.example
file 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.