ZTS Docs

Environment Variables Philosophy

How environment variables are managed and validated.

Core principles

  1. Zod schemas — Variables are defined in packages/env/src/schemas/ and validated at build/start.
  2. Client vs server
    • Client: NEXT_PUBLIC_* in packages/env/src/client.ts
    • Server: packages/env/src/index.ts (serverEnv)
  3. Modular schemas — Feature areas (auth, email, polar, …) merge in packages/env/src/schemas/index.ts
  4. Single source of truth — Import @zts/env / @zts/env/client from apps and packages; do not read process.env ad hoc in feature code.

The web app re-exports schemas under apps/web/src/env/schemas/ for local overrides; canonical definitions are in packages/env.

Application URL

NEXT_PUBLIC_APP_URL is the canonical app origin (auth callbacks, OpenAPI base URL, MCP). Override with SERVER_URL when auto-detection from Vercel/Railway/Render/Coolify is wrong.

Use one deployment per canonical domain when running multiple domains on one host.

Generate a starter .env from env.zerotoshipped.com or copy .env.example at the repo root. Turborepo lists env keys in turbo.json globalEnv for cache correctness.

Debugging pages (web)

  • /envapps/web/src/app/env-client/page.tsx — public NEXT_PUBLIC_* via clientEnv
  • /env-serverapps/web/src/app/env-server/page.tsx — admin-only server env snapshot via packages/trpc admin router

Remove those routes and the getEnvVars admin procedure if you do not want env exposed in the UI.

Mobile / extension

  • Mobile: EXPO_PUBLIC_APP_URL / EXPO_PUBLIC_API_URL (see Mobile)
  • Extension: web URL in options; BETTER_AUTH_TRUSTED_ORIGINS for chrome-extension:// (see Extension)

On this page