Safeguard
Developer Tools•

Vite VITE_ env variables: what reaches the browser and what stays

Vite exposes only VITE_ prefixed variables to client code and bundles them at build time. What that protects, what it does not, and which files to ignore.

Safeguard Security Team
4 min read

Vite exposes only environment variables that start with VITE_ to your client code, and it bundles their values into the build. Variables without the prefix stay out. That protects accidental leaks, but it means VITE_ values are public, so they must never hold API keys or other secrets.

How the prefix works

Vite puts env variables on import.meta.env as strings. The documentation says variables prefixed with VITE_ are exposed in client-side source code after bundling. Its own example makes the point: a VITE_SOME_KEY value is readable in the browser, while DB_PASSWORD from the same file comes back undefined.

The docs also advise avoiding the prefix to prevent accidentally leaking variables. The prefix is the safety catch. Flipping it on a sensitive value removes it.

The explicit warning

Vite states that VITE_ variables should not contain sensitive information such as API keys, because the values are bundled into your source code at build time. For production it points to a backend server or serverless or edge functions to protect secrets.

In practice that means the browser calls your function, and the function holds the key. The browser never sees the credential, and you can rate limit, log and revoke at the function.

Files and what git should ignore

Vite loads several files from the environment directory. A plain .env loads in all cases. .env.local loads in all cases and is ignored by git. Mode files such as .env.production load only in that mode, and their .local variants are git-ignored too.

The docs say .env.*.local files are local only and can contain sensitive variables, and they recommend adding *.local to your .gitignore. Do that on day one.

A subtle point follows from this. The committed .env and .env.production files are for non-sensitive defaults. Real secrets belong in the deployment environment or a secrets service, not in any file the repository tracks.

Precedence can surprise you

Variables that already exist in the environment when Vite starts have the highest priority and are not overwritten by .env files. A mode file beats the generic one. Variables set only in .env or .env.local still apply.

This matters for security in one way: a value you believe comes from production configuration may be silently overridden, or silently missing, depending on what exists in the build environment. Print the resolved non-secret values in the build log for the mode you ship, and check them.

Env files are read at start. Restart the dev server after edits.

Everything is a string

Vite parses values as strings, including booleans. A flag written as false in an env file is the string "false", and a naive truthiness check treats it as on. If a feature or a security toggle is driven by an env variable, convert it explicitly and fail the build on values you do not recognize.

A short review checklist

  • Every VITE_ name is something you would print on your homepage.
  • *.local is in .gitignore.
  • Secrets are read by a server or edge function, not the browser bundle.
  • Booleans are parsed, not compared as strings.
  • The build log shows which mode and which public values were used.

Quick check

Does Vite hide variables without the VITE_ prefix?

Yes from client code. They are not exposed in the browser bundle, but they can still be read by build tooling and server-side code, so keep them out of the repository.

Is it safe to put an API key in VITE_ if the key is restricted?

The docs advise against sensitive values. A restricted key is still public, so treat it as visible and limit what it can do.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.