There is no process in a browser, so Vite exposes environment variables on import.meta.env and only the ones with a prefix.
// .env
VITE_API_URL=https://api.example
DATABASE_PASSWORD=hunter2
// in the app
import.meta.env.VITE_API_URL // 'https://api.example'
import.meta.env.DATABASE_PASSWORD // undefined
import.meta.env.MODE // 'development' | 'production'
import.meta.env.DEV // boolean, statically replaced
The prefix requirement is a security default rather than a convention: without it, a .env holding a database password would be compiled into a file served to the public. The values are replaced at build time by string substitution, which means they are constants in the output and cannot be changed without rebuilding — a container that reads configuration at boot cannot configure a Vite-built frontend, and the usual answer is a small script tag rendered by the server.