Environment Variables
The ElyOS project uses Varlock for typesafe environment variable management. This ensures all configuration is validated and type-safe before the application starts.
Why It Matters
Section titled “Why It Matters”Environment variable management is critical for application functionality:
- Database connection — without
DATABASE_URL, the application won’t start - Authentication —
BETTER_AUTH_SECRETandBETTER_AUTH_URLare required - Email sending — SMTP or other email provider settings
- Secrets management — Infisical integration for secure secrets handling
Three-Layer Architecture
Section titled “Three-Layer Architecture”ElyOS environment variable management consists of three layers:
1. Varlock Schema (.env.schema)
Section titled “1. Varlock Schema (.env.schema)”The source of type definitions and annotations. The TypeScript types file env.d.ts is generated from this.
File: apps/web/.env.schema
Details: Varlock Schema Format →
2. Runtime Validation (schema.ts)
Section titled “2. Runtime Validation (schema.ts)”The runtime validation logic in TypeScript. This validates values loaded from Infisical or .env file.
File: apps/web/src/lib/secrets/schema.ts
Details: Runtime Validation →
3. Central Env Module (env.ts)
Section titled “3. Central Env Module (env.ts)”The typesafe access point from application code.
File: apps/web/src/lib/env.ts
Usage:
import { env } from '$lib/env';
const port = env.ELYOS_PORT; // numberconst devMode = env.DEV_MODE; // booleanconst dbUrl = env.DATABASE_URL; // stringStartup Modes
Section titled “Startup Modes”Development (Local .env)
Section titled “Development (Local .env)”bun app:devLoads variables from .env.local file. Fast and simple for local development.
Development (Varlock + Infisical)
Section titled “Development (Varlock + Infisical)”bun app:dev:varlockLoads variables from Infisical. Use for testing if you want configuration similar to production.
Production (Docker)
Section titled “Production (Docker)”CMD ["varlock", "run", "--", "bun", "run", "apps/web/server.js"]Only bootstrap credentials are in the .env file, everything else comes from Infisical.
Details: Startup Modes and Infisical →
Adding a New Variable
Section titled “Adding a New Variable”If you add a new environment variable, you need to update 3 places:
.env.schema— with Varlock annotationsschema.ts— in 4 places (EXPECTED_KEYS, REQUIRED_KEYS, validateSchema, validEnvArbitrary).env.example— with example value
Detailed guide: Adding a New Variable →
File Structure
Section titled “File Structure”elyos-core/├── .env.example # Example configuration├── .env.local # Local development variables (gitignore)├── apps/web/│ ├── .env.schema # Varlock schema (@generateTypes)│ ├── src/│ │ ├── env.d.ts # Generated TypeScript types│ │ ├── lib/│ │ │ ├── env.ts # Central env export│ │ │ └── secrets/│ │ │ ├── varlock.ts # Infisical integration│ │ │ └── schema.ts # Runtime validation│ │ └── server.js # Express + Socket.IO server│ └── vite.config.ts # envDir: '../..'Benefits
Section titled “Benefits”- Type Safety — full TypeScript support
- Validation — schema-based validation at startup and runtime
- Secrets Management — centralized Infisical integration
- Fallback — local development support
- Coercion — automatic type conversion (string → boolean/number)
- Token Renewal — automatic token refresh
- Retry Logic — fault-tolerant connection (3 retries)
Next Steps
Section titled “Next Steps”- Varlock Schema Format → — annotations, types, functions
- Infisical Integration → — bootstrap credentials, how it works
- Runtime Validation → — schema.ts in detail
- Adding a New Variable → — step-by-step guide