The Culprit: Why 'process' breaks in ViteSwitching from Create React App (CRA) to Vite usually feels like moving from a cargo ship to a speedboat. However, if you try to access environment variables the old way, your app will likely crash before it even loads.
// ❌ This triggers the error in Vite
const apiKey = process.env.VITE_API_KEY;
In the browser console, you'll see a hard stop:
Uncaught ReferenceError: process is not defined
This happens because process is a Node.js global variable, not a browser one. Webpack (which CRA uses) automatically adds 'polyfills'—extra code that mimics Node.js environments in the browser. Vite stays lean by avoiding these shims. This keeps your dev server start times under 300ms, but it means you must use modern web standards instead of Node-specific globals.
Two-Minute DebugBefore changing your config, pinpoint where the error originates. Ask yourself:
- Is it my code? Look for
process.envin your components.- Is it a library? Check if an older NPM package is expecting a Webpack-like environment.Vite replacesprocess.envwithimport.meta.env. If your own code is the issue, the fix is a simple find-and-replace. If a third-party dependency is crashing, you'll need a configuration shim.
Solution 1: Use the Vite Native Syntax (Best Practice)Vite uses ES Modules (ESM) syntax. This is the standard for modern JavaScript and the most efficient way to handle variables.
Step 1: The VITE_ PrefixYour variables in .env must start with VITE_. If they don't, Vite ignores them to prevent you from accidentally leaking sensitive system keys (like your computer's username) into the public browser bundle.
# .env
VITE_API_URL=https://api.example.com
VITE_STRIPE_KEY=pk_test_12345
Step 2: Update your codeSwap out the old Webpack syntax for the ESM equivalent. It's a direct replacement.
// ❌ Old Way (CRA/Webpack)
const url = process.env.VITE_API_URL;
// ✅ New Way (Vite)
const url = import.meta.env.VITE_API_URL;
Solution 2: Fixing Legacy Library CrashesSometimes you aren't the one calling process.env—your dependencies are. If you're using an older package that hasn't been updated since 2020, it might still rely on Webpack's automatic polyfills. You can patch this in vite.config.js using the define property.
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
define: {
// This creates a global 'process.env' object so libraries don't crash
'process.env': {}
}
});
This 'shim' ensures that when a library looks for process.env, it finds an empty object instead of a null reference. It's a quick band-aid that gets your app running without a full refactor.
Solution 3: TypeScript IntelliSenseDoes import.meta.env have a red squiggly line underneath it? TypeScript needs to know about Vite's special types. Create or update src/vite-env.d.ts to fix your IDE warnings:
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_URL: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}
Verifying the FixRestart your dev server (npm run dev). Don't trust your eyes; check the console. Add a temporary log to your App.tsx:
console.log('API Target:', import.meta.env.VITE_API_URL);
console.log('Current Mode:', import.meta.env.MODE);
If the values appear and the ReferenceError is gone, you’ve successfully migrated to Vite’s native environment handling.

