Lesson 7 of 8 intermediate 5 min read

Environment Variables

Static vs dynamic, public vs private ($env/static/private, $env/dynamic/public) security.

Interactive Laboratory

Live Runtime

Experiment directly with Environment Variables concepts in real time

Environment Security Matrix
Target Scope: Server-Only (Private Fence)
Evaluation Time: Build-Time (Constant Inlined)

Environment Variables and Security

SvelteKit provides four specialized $env modules to prevent secrets leakage and maximize compile-time dead-code elimination.


1. The Four $env Modules

ModuleAccessEvaluated AtUse Case
$env/static/privateServer OnlyBuild TimeDatabase credentials, API secrets, Stripe private keys.
$env/static/publicClient & ServerBuild TimePublic keys, Supabase URLs, analytics tracking IDs.
$env/dynamic/privateServer OnlyRuntimeSecrets read dynamically per request from process environment.
$env/dynamic/publicClient & ServerRuntimePublic values configured per deployed container/instance.

2. Compile-Time Inlining ($env/static/private)

Static variables are replaced with constant values during build time, allowing compilers to eliminate unreachable branches:

// src/lib/server/stripe.ts
import { STRIPE_SECRET_KEY } from '$env/static/private';
import Stripe from 'stripe';
 
export const stripe = new Stripe(STRIPE_SECRET_KEY);

[!CAUTION] If you accidentally import from $env/static/private inside client code (+page.svelte or +page.ts), SvelteKit will halt the build with an error to prevent exposing secrets in the client bundle.


3. Public Variables Prefix (PUBLIC_)

Public variables must start with PUBLIC_ (configured via publicPrefix in svelte.config.js):

// src/routes/+layout.svelte
import { PUBLIC_ANALYTICS_ID } from '$env/static/public';