Configuration
Every environment variable IsotopeAI reads, what consumes it, and
which ones are safe to share. Configuration lives in .env at the
repository root.
Never commit .envIt is listed in .gitignore along with
.env.*. CI fails the build if .env becomes tracked, and it
scans for service keys and access tokens in any non-ignored file.
Required #
Only two variables are strictly required. A fresh install ships a
.env pre-filled with a shared demo project so the app boots before you
have your own database.
- SUPABASE_URL
- Your project URL, e.g.
https://abcdefgh.supabase.co. Validated at startup — the server exits if it is not a well-formed Supabase URL. - SUPABASE_ANON_KEY
- The public anon JWT. Safe to expose; it is injected into the browser and every request it makes is still subject to row-level security.
Optional #
- PORT
- HTTP port. Defaults to
3000. - GITHUB_OWNER
- Repo owner for update checks. Defaults to
Suydev. - GITHUB_REPO
- Repo name for update checks. Defaults to
isotope-code. - GITHUB_PAT
- Raises the GitHub API rate limit for update checks. Not required.
- ASSET_CDN_ORIGINS
- Comma-separated origins used to recover a missing
/assets/*file. Recovered files still pass through the patcher. - GEMINI_API_KEY
- Enables Gemini-backed AI features.
- GROQ_API_KEY
- Enables Groq-backed AI features.
- ISOTOPE_HOME
- State directory for pid file, port and logs. Defaults to
~/.isotope.
Owner only #
These unlock the admin console and server-side data management. Leave them blank
for a normal install — every /__admin/* route returns a disabled page
unless admin mode is explicitly on.
- ENABLE_ADMIN_MODE
- Must be
trueand a service-role key must be present before any admin route works. - SUPABASE_SERVICE_ROLE_KEY
- Bypasses row-level security. Required for
ADMIN_MODE_READYand for the startup backfills. Never sent to the browser. - SUPABASE_ACCESS_TOKEN
- Management API personal access token. Only needed for
one-click SQL apply via
/__admin/patch. - ADMIN_SECRET
- Unlock secret for
/__admin/login. When unset, the admin cookie signing key is a fresh random value each boot, so an unlock does not survive a restart. - ADMIN_EMAIL
- Supabase account email allowed to unlock admin mode.
- ADMIN_EMAILS
- Comma-separated allowlist of admin emails.
- ADMIN_PASSWORD
- Used only by the optional admin account bootstrap on startup.
- BROWSER_PROOF_EMAIL
- Existing user for
/__admin/browser-proof. Falls back toADMIN_EMAIL. - SHOT_EMAIL / SHOT_PASSWORD
- Dedicated account used by
capture-screenshots.mjs --loginso authenticated routes render.
Two keys must stay privateSUPABASE_SERVICE_ROLE_KEY
bypasses RLS entirely and SUPABASE_ACCESS_TOKEN can run arbitrary SQL
through the Management API. Both are read only inside server handlers and are never
injected into a page.
Present but not read #
Two variables appear in .env.example for forward compatibility but
nothing in server.mjs consumes them today:
| Variable | Status |
|---|---|
YEPAPI_KEY | Reserved for planned /__ai/* routes. That prefix is fenced to a 404 and has no handler. |
SESSION_SECRET | Set by CI and release workflows, but the server never reads it. |
Precedence #
Host environment wins over .env. The loader only fills variables that
are not already set, so PORT=4000 isotope start overrides the file
without editing it.
# inspect what the server actually resolved curl -s http://127.0.0.1:3000/api/version | python3 -m json.tool # admin mode readiness, without revealing key material isotope doctor
Applying changes #
.env is read once at startup. Restart after editing it:
isotope restart