Web app (frontend)
The web app has no validated env schema. Variables are read where they are used. The scripts in the root package.json wrap Turborepo with dotenv -c, which loads .env and then .env.local from the repository root.
There is no .env.example in the repository at the time of writing.
Required
Optional
Build-time only
The Dockerfile and the CI workflows also setDATABASE_URL and BETTER_AUTH_SECRET to placeholder values during the build. The web app no longer opens a database connection or runs better-auth in process, so these are not needed at runtime. A local .env may still contain a DATABASE_URL from before the consolidation. It can be removed.
The boundary check
pnpm check:core-api runs tools/check-no-direct-core-api.sh. It fails when:
- any file other than
apps/saas/modules/shared/lib/core-api.tsmentionsCORE_API_URLorSERVICE_AUTH_SECRET, - a variable named
NEXT_PUBLIC_CORE_API...exists, - a
"use client"file importscore-apior callscoreApiFetch, core-api.tsis missing or does not importserver-only.
At the time of writing, several other files also read
CORE_API_URL: bff-proxy.ts, bff-server-fetch.ts, modules/admin/lib/admin-api.ts, and the route handlers under app/api/onboarding and app/api/waitlist. The script allows only core-api.ts, so it reports these files. CI runs the script as its first step. Either the allow list or those files need to change before the check passes.Mobile app (mobile)
The mobile app reads only EXPO_PUBLIC_* variables at runtime. Expo inlines them into the JavaScript bundle at build time, so they are public. Never put a secret in one.
mobile/.env.example is in the repository. .env and .env.production are ignored by Git.