Skip to content

Env Variables & Modes

Vantris loads .env files based on the active mode and exposes a curated, prefixed subset to your client code through import.meta.env. Secrets stay out of the bundle by design.

Modes

Every command runs in a mode — a label that drives which .env files load and what import.meta.env.MODE resolves to.

  • vantris dev defaults to mode development.
  • vantris build and vantris preview default to mode production.

Override the mode with --mode:

bash
vantris dev --mode staging
vantris build --mode production
vantris preview --mode local

.env files

The mode selects which files load. Later files override earlier ones:

text
.env                  # always loaded
.env.local            # always loaded, git-ignored
.env.[mode]           # e.g. .env.production
.env.[mode].local     # e.g. .env.production.local, git-ignored

Git-ignore the .local files

.env.local and .env.[mode].local are meant for machine-specific values and secrets. Add *.local to .gitignore so they never get committed.

Example set:

bash
# .env
VANTRIS_APP_NAME=My App

# .env.production
VANTRIS_API=https://api.example.com

# .env.development
VANTRIS_API=http://localhost:8080

Exposing variables to the client

Only variables prefixed VANTRIS_ are exposed to client code via import.meta.env. This is the safety boundary — an unprefixed secret in .env (a database URL, an API key) never reaches the bundle.

ts
// .env.production → VANTRIS_API=https://api.example.com
console.log(import.meta.env.VANTRIS_API); // "https://api.example.com"
bash
# .env
VANTRIS_PUBLIC_KEY=pk_live_123    # ✅ exposed
DATABASE_URL=postgres://…          # ❌ never exposed (no VANTRIS_ prefix)

Built-in variables

Alongside your prefixed variables, import.meta.env always includes:

VariableTypeValue
MODEstringThe active mode ("development", "production", …).
DEVbooleantrue when the mode is not "production".
PRODbooleantrue when the mode is "production".
BASE_URLstringThe configured base path.
ts
console.log(import.meta.env.MODE, import.meta.env.PROD); // "production" true

if (import.meta.env.DEV) {
  // development-only code
}

How values are injected

import.meta.env accesses are statically replaced at dev and build time — they're not read from a runtime object. So import.meta.env.PROD becomes the literal true/false, and a branch guarded by import.meta.env.DEV is tree-shaken out of the production build, exactly like define.

TypeScript

vantris/client types import.meta.env, including the built-ins and any VANTRIS_-prefixed key:

jsonc
// tsconfig.json
{ "compilerOptions": { "types": ["vantris/client"] } }
ts
import.meta.env.MODE;          // string
import.meta.env.PROD;          // boolean
import.meta.env.VANTRIS_API;   // string | undefined

See Client Types for the full ambient declaration.

Env vs. define

Both inline values at build time. Use whichever fits:

import.meta.envdefine
Source.env filesvantris.config.ts
Mode-aware✅ (files per mode)manual
Prefix guardVANTRIS_ requirednone — you choose the keys
Best forper-environment URLs, flagsconstants, metadata, feature flags

Released under the MIT License.