Install
$ agentstack add skill-impertio-studio-vite-claude-skill-package-vite-syntax-env-vars ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
vite-syntax-env-vars
Quick Reference
Built-in Constants (import.meta.env)
| Property | Type | Description | |----------|------|-------------| | import.meta.env.MODE | string | Current mode ("development", "production", or custom) | | import.meta.env.BASE_URL | string | Base URL from base config option | | import.meta.env.PROD | boolean | true when running in production | | import.meta.env.DEV | boolean | true when running in development (ALWAYS inverse of PROD) | | import.meta.env.SSR | boolean | true when running server-side |
.env File Loading Order (Priority: Low to High)
| Priority | File | Loaded When | Gitignored | |----------|------|-------------|------------| | 1 (lowest) | .env | All modes | No | | 2 | .env.local | All modes | Yes | | 3 | .env.[mode] | Matching mode only | No | | 4 | .env.[mode].local | Matching mode only | Yes | | 5 (highest) | OS environment variables | Always | N/A |
OS environment variables ALWAYS take highest priority and NEVER get overwritten by .env files.
Critical Warnings
> NEVER set envPrefix to '' (empty string). This exposes ALL environment variables to client-side code, including secrets like DB_PASSWORD, AWS_SECRET_KEY, and session tokens. This is a critical security vulnerability.
> NEVER put secrets in VITE_-prefixed variables. Any variable with the VITE_ prefix is embedded in the client bundle and visible to anyone inspecting the browser source. Use server-side environment variables or a backend API for secrets.
VITE_ Prefix Rule
Only variables prefixed with VITE_ are exposed to client code via import.meta.env:
VITE_API_URL=https://api.example.com # Exposed: import.meta.env.VITE_API_URL
VITE_APP_TITLE=My App # Exposed: import.meta.env.VITE_APP_TITLE
DB_PASSWORD=secret123 # NOT exposed: import.meta.env.DB_PASSWORD === undefined
SECRET_KEY=abc # NOT exposed: import.meta.env.SECRET_KEY === undefined
ALWAYS use the VITE_ prefix for any variable that needs to reach client-side code.
Decision Trees
Which env approach to use?
Need env variable in CLIENT-SIDE code?
├── Yes → Prefix with VITE_ and access via import.meta.env.VITE_*
│ Is it a secret (API key, password, token)?
│ ├── Yes → STOP. NEVER put secrets in VITE_* vars.
│ │ Use a backend proxy or server-side API instead.
│ └── No → Safe to use VITE_* prefix
└── No → Need it in vite.config.ts?
├── Yes → Use loadEnv(mode, envDir, prefixes) to load it
└── No → Use standard process.env (Node.js server-side only)
Which .env file to use?
Variable needed in ALL environments?
├── Yes → Put in .env
│ Is it sensitive/local-only?
│ ├── Yes → Put in .env.local (gitignored)
│ └── No → Put in .env (committed)
└── No → Put in .env.[mode] (e.g., .env.staging, .env.production)
Is it sensitive/local-only?
├── Yes → Put in .env.[mode].local (gitignored)
└── No → Put in .env.[mode] (committed)
NODE_ENV vs Mode
These are two DIFFERENT concepts. NEVER confuse them.
| Command | NODE_ENV | Mode | .env files loaded | |---------|----------|------|-------------------| | vite (dev server) | "development" | "development" | .env, .env.development | | vite build | "production" | "production" | .env, .env.production | | vite build --mode staging | "production" | "staging" | .env, .env.staging | | vite build --mode development | "production" | "development" | .env, .env.development | | NODE_ENV=development vite build | "development" | "production" | .env, .env.production |
Key distinction:
- NODE_ENV is set by the Vite command (
vite= development,vite build= production) and controlsimport.meta.env.PROD/DEV - Mode controls which
.env.[mode]files are loaded and setsimport.meta.env.MODE - The
--modeflag changes mode WITHOUT changing NODE_ENV - ALWAYS use
--modefor custom environments (staging, test, QA)
Config Options
envDir
- Type:
string | false - Default:
root(project root) - Directory to load
.envfiles from - Set to
falseto disable.envfile loading entirely
envPrefix
- Type:
string | string[] - Default:
"VITE_" - Controls which env variables are exposed to
import.meta.env - ALWAYS keep a meaningful prefix — NEVER set to empty string
export default defineConfig({
envPrefix: ['VITE_', 'PUBLIC_'], // Expose both VITE_* and PUBLIC_* vars
})
loadEnv()
Use loadEnv() to access env variables inside vite.config.ts:
import { defineConfig, loadEnv } from 'vite'
export default defineConfig(({ mode }) => {
// Load env files from cwd, only VITE_-prefixed vars
const env = loadEnv(mode, process.cwd())
// Load ALL env vars (including non-prefixed)
const allEnv = loadEnv(mode, process.cwd(), '')
return {
define: {
__APP_ENV__: JSON.stringify(allEnv.APP_ENV),
},
}
})
Signature: loadEnv(mode: string, envDir: string, prefixes?: string | string[])
mode: The mode to load (e.g.,'development','production','staging')envDir: Directory containing.envfilesprefixes: Filter by prefix. Default'VITE_'. Pass''to load all variables.
Variable Expansion (dotenv-expand)
Vite uses dotenv-expand to expand variables within .env files:
BASE_URL=https://example.com
API_URL=$BASE_URL/api # https://example.com/api
ESCAPED=test\$BASE_URL # test$BASE_URL (literal dollar sign)
UNDEFINED=$NONEXISTENT # "" (empty string)
Use \$ to escape a literal dollar sign. Undefined variables expand to empty string.
TypeScript IntelliSense
ALWAYS define custom env variables in a type declaration file for full IntelliSense:
// src/vite-env.d.ts
///
interface ImportMetaEnv {
readonly VITE_APP_TITLE: string
readonly VITE_API_URL: string
readonly VITE_ENABLE_ANALYTICS: string
// Add all custom VITE_* variables here
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
NEVER omit the /// triple-slash directive — it provides types for all built-in constants (MODE, BASE_URL, PROD, DEV, SSR).
HTML Env Replacement
Use %ENV_VAR% syntax in index.html to inject env variables:
%VITE_APP_TITLE%
Running in %MODE% mode
- All
import.meta.envproperties are available (built-in + VITE_-prefixed) - Non-existent variables are silently ignored (no error, no replacement)
- This replacement happens at build time — values are statically embedded
Reference Links
- [references/config-options.md](references/config-options.md) -- envDir, envPrefix, loadEnv signature, .env loading precedence details, mode config
- [references/examples.md](references/examples.md) -- Complete .env file examples, TypeScript IntelliSense setup, HTML replacement, custom modes, loadEnv patterns
- [references/anti-patterns.md](references/anti-patterns.md) -- Common environment variable mistakes and security pitfalls
Official Sources
- https://vite.dev/guide/env-and-mode
- https://vite.dev/config/shared-options#envdir
- https://vite.dev/config/shared-options#envprefix
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Impertio-Studio
- Source: Impertio-Studio/Vite-Claude-Skill-Package
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.