Free workshop: build with AI without losing control of your project View the workshop →
vibebusters

← Full glossary

// glossary

Environment variables: configuration kept out of the code

In short

Environment variables are settings passed to an application when it starts or is built, instead of being written into the code: database address, service keys, test or production mode. They let the same code run in several environments and keep secrets out of the repository.

An application needs to know which database to connect to, which key to use for sending emails and whether it is running in test or production. Writing that information into the code means changing the code at every change, and exposes the keys to anyone who reads the repository. Environment variables solve both problems: the code asks for a value by name, and each environment supplies its own.

How it works

An environment variable is a name and value pair, for example STRIPE_SECRET_KEY=sk_live_.... The code only contains the name. At startup or build time, the host or the .env file supplies the value.

The same code can then run in three places with three configurations:

Environment Database Payments
Developer machine Local database Stripe test key
Staging Test database Stripe test key
Production Real database Stripe live key

This split is what makes a serious staging environment possible, where you test a change without touching real data or real payments.

The distinction that matters: browser or server

A modern app has two categories of variables, and confusing them is one of the most common causes of an exposed secret.

Browser variables are read at build time and copied into the JavaScript sent to every visitor. With Vite, these are the ones starting with VITE_. The Vite documentation states that they should not contain sensitive information such as API keys. They are fine for the public Supabase URL, its publishable key or an analytics ID.

Server variables stay on the server and are never sent to the browser. On Supabase, these are Edge Function secrets, set in the dashboard or with supabase secrets set, then read in code with Deno.env.get. That is where the Supabase secret key and the payment, email or AI model keys belong. Supabase notes that deployed functions pick up a new secret without a redeploy.

Why it is a key point in a handover

The code leaves with the GitHub export. The variable values do not. That is intentional, since secrets should not be in the repository, but it creates a blind spot during a handover or a change of host: the migrated app starts, then payments, emails or sign-in fail one after another, for lack of configuration.

Our guide on exporting and owning the code details what travels with the repository. Variables are part of what must be inventoried separately, along with the account owner of each service.

How to check your app

  1. Look for a .env.example file or a documented list of required variables. If none exists, the handover will start with an investigation
  2. List the VITE_ or NEXT_PUBLIC_ variables and check that none holds a secret
  3. Check the .gitignore: .env, .env.local and *.local should be excluded from the repository, as Vite recommends
  4. Inventory the server-side secrets in the Supabase or platform dashboard, with the service involved and the owning account
  5. Check the separation between test and production: different keys, a different database, and no live key on a developer's machine

A concrete example

A startup brings an app built with Replit in house. The code is on GitHub, the new host is ready. On first launch, the home page loads. Sign-ups fail: the email service key was never written down anywhere. Payments fail too: the Stripe key was registered on the account of the freelancer who started the project.

It took two days to track down the accounts, regenerate the keys and restore service. A fifteen-line inventory, prepared before the migration, would have cut that to an hour.

The most common mistakes

  • A secret in a VITE_ or NEXT_PUBLIC_ variable, and therefore published
  • A versioned .env file, sometimes since the first commit
  • No documentation of the variables, known only to the tool or the freelancer
  • The same values in test and production
  • Secrets registered on a personal account rather than the company's

The takeaway

Environment variables are a simple good practice that only asks for one discipline: knowing which ones are public, which ones are secret, and where each one is stored. The vibebusters Scan produces that inventory, and the checklist places it among the points to check before a handover.

// faq

The questions we keep hearing

Is an environment variable always secret?

No. In a front-end app built with Vite, any variable prefixed with VITE_ is copied into the code sent to the browser and becomes public. Only variables read on the server, for example in an Edge Function, stay private.

What does a .env file contain, and should it go on GitHub?

A .env file lists NAME=value pairs loaded at startup or build time. It must not be versioned if it contains secrets: add it to .gitignore and provide a .env.example file instead, with the variable names but no values.

Where are the variables of a Lovable or Supabase app stored?

Public values are often in a .env file in the project. Server function secrets are stored in the Supabase dashboard, under Edge Function Secrets, or in the platform's secrets manager. Take stock of them before any migration, because they do not leave with the code export.

Prepare the configuration before a handover

The Scan inventories your app's variables and secrets, shows where they live and what must be recreated with another host.

See what the Scan covers