Are Vite environment variables public?
Yes. Any variable that starts with VITE_ and that your code reads through import.meta.env is written into your built JavaScript as plain text. Anyone can read it in the browser.
Why this catches people
The variable lives in a .env file, which feels private. But Vite replaces import.meta.env.VITE_OPENAI_KEY with the actual value at build time. The secret ends up in a file like /assets/index-abc123.js that every visitor downloads.
Variables without the VITE_ prefix aren't exposed, but they also aren't available in your browser code at all. That's the point: a Vite app runs entirely in the browser, so there is no safe place in it for a secret.
What's fine to put in VITE_ variables
- Public URLs (your API base URL, your Supabase project URL)
- Keys that are designed to be public: Supabase anon/publishable keys, Firebase config, Stripe publishable keys (
pk_), browser-restricted Google Maps keys
What is never fine
- OpenAI, Anthropic, Groq, Replicate or any AI provider key
- Stripe secret keys (
sk_) - Database passwords, service role keys, email API keys
The fix
- Rotate any secret that was ever in a
VITE_variable on a deployed site. - Move the call that needs it into a small server function: a Vercel or Netlify function, a Cloudflare Worker, or a Supabase Edge Function. Keep the key in that platform's environment settings, without the
VITE_prefix. - Have your app call your function instead of the provider directly.