Environment Variables
saaskip uses @t3-oss/env-nextjs with zod for typed, validated environment variables.
How it works
Environment variables are defined in src/core/env/index.ts and validated at startup. Invalid or missing required variables throw a clear error before the app boots.
ts
import { createEnv } from '@t3-oss/env-nextjs';
import z from 'zod';
export const env = createEnv({
server: {
NODE_ENV: z
.enum(['development', 'test', 'production'])
.default('development'),
// add server-only vars here
},
client: {
NEXT_PUBLIC_APP_URL: z.url(),
// add client-accessible vars here
},
experimental__runtimeEnv: {
NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
},
});Server vs Client
| Scope | Prefix | Accessible where |
|---|---|---|
server | none | Server only |
client | NEXT_PUBLIC_ | Server and client |
WARNING
Never put secrets in client variables. They are exposed to the browser.
Adding a new variable
- Add it to
.envand.env.example - Add a zod schema in the appropriate section (
serverorclient) - If client-side, add it to
experimental__runtimeEnv - Import
envwhere needed:import { env } from '@/core/env'
skipValidation
Validation is skipped in these cases:
SKIP_ENV_VALIDATIONenv var is set- Running on Vercel (
VERCELenv var) - During build (
npm_lifecycle_event === 'build') - In test mode (
NODE_ENV === 'test')
This prevents CI and test runners from failing on missing env vars.
Reference
See .env.example for the full list of variables and their descriptions.