Are VITE_ environment variables secret? No, and here's how keys leak from Lovable and Bolt apps A developer published a guide explaining that Vite's VITE_-prefixed environment variables are embedded into client-side JavaScript bundles at build time and are therefore publicly readable, with the same applying to Next.js's NEXT_PUBLIC_ and Create React App's REACT_APP_ prefixes. The writeup details how secret keys leak from AI-built apps such as Lovable, Bolt and Cursor frontends, lists which key types are safe to expose (Supabase publishable keys with Row Level Security, Stripe pk_ keys, PostHog phc_ keys) versus which must stay server-side (OpenAI sk-proj-, Anthropic sk-ant-, Supabase sb_secret_, Stripe sk_live_), and recommends moving secret-key calls into Supabase Edge Functions using supabase secrets set. Short answer: no. In a Vite app, every environment variable that starts with VITE is written into your JavaScript bundle at build time. That bundle is downloaded by every visitor, so anyone can read the value in DevTools. The same is true of NEXT PUBLIC in Next.js and REACT APP in Create React App. Vite hides variables without the VITE prefix from your frontend code on purpose. The prefix is how you tell Vite "this value is safe to publish". Here's how secret keys usually end up public in AI-built apps: import.meta.env.OPENAI API KEY . undefined in the browser, so the feature breaks. VITE OPENAI API KEY . Lovable, Bolt and most Cursor-built frontends are Vite apps, so this comes up a lot. VITE variable sb publishable key, as long as Row Level Security is on for every table pk live , pk test phc , Sentry DSNs sk-proj- , Anthropic sk-ant- , Groq, Replicate sk live and webhook secrets whsec sb secret key, which bypasses RLS entirely re , SendGrid SG. , AWS keys, database URLs with a password Not sure which kind a key is? I made a free key checker https://www.getleakpatrol.com/api-key-checker.html?ref=devto that tells you what a key is and whether it's allowed in the browser. It runs entirely client-side, so the key never leaves the page. supabase secrets set OPENAI API KEY=... . A prompt that works in Lovable, Bolt or Cursor: Move every call that uses a secret API key out of the frontend into a Supabase Edge Function that reads the key from Supabase secrets. Remove the VITE variable for it and call the function instead. Only allow logged-in users to call it. Don't print any keys in your reply. Your .env file isn't what matters. What matters is what ended up in the built JavaScript. Two ways to check: sk- , sk live , service role and .env files, source maps and missing headers. The full version of this guide, with a FAQ, is here https://www.getleakpatrol.com/vite-env-variables-secret.html .