Reference for every environment variable this Next.js app reads, where it's
validated, and how it affects behavior across local dev, testnet, and
mainnet. The authoritative schema lives in src/lib/env.ts; this doc is a
narrative companion to the table in the root README.md.
cp .env.example .env.local
# edit .env.local with real values, then:
pnpm run devEvery variable is optional locally. Leaving .env.local empty (or not
creating it at all) still works — next dev and pnpm test both run
against in-repo mocks (/api/auth/login, /api/wallets, etc.).
These are inlined into the browser bundle at build time. Never put secrets
in a NEXT_PUBLIC_* variable.
NEXT_PUBLIC_API_URL— primary backend base URL. Read directly insrc/app/api/auth/login/route.tsto decide whether to proxy to a real backend or fall back to the mock login response, and insrc/lib/api/config.ts::getApiBaseUrl()as the first candidate for all other API calls (e.g.useWallets).NEXT_PUBLIC_MUX_API_URL— second candidate in the samegetApiBaseUrl()fallback chain; defaults tohttps://api.muxprotocol.comwhen nothing else is set. PredatesNEXT_PUBLIC_API_URLand is kept for older deploy configs.NEXT_PUBLIC_API_BASE— third and final candidate in the fallback chain, for deploys that used this older name.NEXT_PUBLIC_APP_URL— this app's own public URL; defaults tohttp://localhost:3000.NEXT_PUBLIC_MUX_API_KEY— read bygetApiKey()insrc/lib/api/config.ts; attached to outgoing API requests where a client-visible key is acceptable.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID— only relevant if WalletConnect-based wallet flows are enabled.
These never reach the browser and are safe for secrets.
MUX_API_KEY/MUX_API_SECRET— credentials for server-side calls to the Mux Protocol API (Next.js route handlers / server components only).DATABASE_URL— connection string, if this deployment persists any data outside the backend API.
NODE_ENV— standard Next.js variable. Gates verbose console logging in the analytics/tracking hooks (useAnalytics.ts,useAnalyticsMetrics.ts,useAnalyticsTracking.ts,recoveryAnalyticsTracking.ts,spendingLimitsTracking.ts) outside ofproduction, and makesvalidateEnv()insrc/lib/env.tsthrow (instead of warn) on missing required vars when set toproduction.
This app has no built-in network switch — network selection is entirely a
function of which backend NEXT_PUBLIC_API_URL (or its aliases) points
at:
| Environment | NEXT_PUBLIC_API_URL example |
|---|---|
| Local dev (mocked) | (unset) |
| Testnet / staging | https://testnet-api.muxprotocol.com |
| Mainnet / production | https://api.muxprotocol.com |
The wallet rows themselves also carry a per-wallet network field
("testnet" | "mainnet", see src/types/wallet.ts), so a single
backend can return a mix of both — the env var controls which backend
you talk to, not which network's wallets are shown.
.github/workflows/ci.yml sets NEXT_PUBLIC_API_URL=https://api.example.com
purely so next build succeeds without real credentials. It is a
placeholder, not a real environment — do not read it as evidence of a
live mainnet or testnet target.
-
.env.localunset entirely →pnpm run devstill boots and login succeeds against the mock/api/auth/loginroute. -
NEXT_PUBLIC_API_URLset to a real backend → login proxies through instead of using the mock. -
NEXT_PUBLIC_APP_URLchanged → any absolute links that use it update accordingly. - Removing a
NEXT_PUBLIC_*var and settingNODE_ENV=productionsurfaces a startup error only for vars markedrequiredinsrc/lib/env.ts(none currently are, by design).