Environment Variables Reference for the Tanstack Start Supabase SaaS Kit

Complete reference for all environment variables in the Tanstack Start Supabase SaaS Kit, including Supabase, Stripe, email, and feature flag configuration.

This page documents all environment variables used by the Tanstack Start Supabase SaaS Kit. Variables are organized by category and include their purpose, required status, and default values.

Environment File Structure

FilePurposeGit Status
.envShared settings across all environmentsCommitted
.env.developmentDevelopment-specific overridesCommitted
.env.productionProduction-specific settingsCommitted
.env.localLocal secrets and overridesGit-ignored

Priority order: .env.local > .env.development/.env.production > .env

Required Variables

These variables must be set for the application to start:

# Supabase (required)
VITE_SUPABASE_URL=https://yourproject.supabase.co
VITE_SUPABASE_PUBLIC_KEY=your-public-key
SUPABASE_SECRET_KEY=your-service-role-key
# App identity (required)
VITE_SITE_URL=https://yourapp.com
VITE_PRODUCT_NAME=Your Product
VITE_SITE_TITLE="Your Product - Tagline"
VITE_SITE_DESCRIPTION="Your product description"

Core Configuration

Site Identity

VITE_SITE_URL=https://example.com
VITE_PRODUCT_NAME=Makerkit
VITE_SITE_TITLE="Makerkit - Build SaaS Faster"
VITE_SITE_DESCRIPTION="Production-ready SaaS starter kit"
VITE_DEFAULT_LOCALE=en
VariableRequiredDescription
VITE_SITE_URLYesFull URL with protocol
VITE_PRODUCT_NAMEYesProduct name shown in UI
VITE_SITE_TITLEYesBrowser title and SEO
VITE_SITE_DESCRIPTIONYesMeta description
VITE_DEFAULT_LOCALENoDefault language (default: en)

Theme

VITE_DEFAULT_THEME_MODE=light
VITE_THEME_COLOR="#ffffff"
VITE_THEME_COLOR_DARK="#0a0a0a"
VITE_ENABLE_THEME_TOGGLE=true
VariableOptionsDefaultDescription
VITE_DEFAULT_THEME_MODElight, dark, systemlightInitial theme
VITE_THEME_COLORHex colorRequiredLight theme color
VITE_THEME_COLOR_DARKHex colorRequiredDark theme color
VITE_ENABLE_THEME_TOGGLEtrue, falsetrueAllow theme switching

Supabase Configuration

VITE_SUPABASE_URL=https://yourproject.supabase.co
VITE_SUPABASE_PUBLIC_KEY=your-public-key
SUPABASE_SECRET_KEY=your-service-role-key
SUPABASE_DB_WEBHOOK_SECRET=your-webhook-secret
VariableRequiredDescription
VITE_SUPABASE_URLYesSupabase project URL
VITE_SUPABASE_PUBLIC_KEYYesPublic anon key
SUPABASE_SECRET_KEYYesService role key (keep secret)
SUPABASE_DB_WEBHOOK_SECRETNoWebhook verification secret

Authentication

VITE_AUTH_PASSWORD=true
VITE_AUTH_MAGIC_LINK=false
VITE_AUTH_OTP=false
VITE_AUTH_PASSKEY=false
VITE_AUTH_IDENTITY_LINKING=false
VITE_CAPTCHA_SITE_KEY=
CAPTCHA_SECRET_TOKEN=
VITE_CAPTCHA_WIDGET_SIZE=invisible
VITE_DISPLAY_TERMS_AND_CONDITIONS_CHECKBOX=false
VariableDefaultDescription
VITE_AUTH_PASSWORDtrueEnable password auth
VITE_AUTH_MAGIC_LINKfalseEnable magic link auth
VITE_AUTH_OTPfalseEnable OTP auth
VITE_AUTH_PASSKEYfalseEnable passkey (WebAuthn) auth
VITE_AUTH_IDENTITY_LINKINGfalseAllow identity linking
VITE_CAPTCHA_SITE_KEY-Cloudflare Turnstile site key
CAPTCHA_SECRET_TOKEN-Cloudflare Turnstile secret
VITE_CAPTCHA_WIDGET_SIZEinvisibleTurnstile widget size. Set to normal or compact with a Managed site key
VITE_DISPLAY_TERMS_AND_CONDITIONS_CHECKBOXfalseShow terms checkbox

Password Requirements

VITE_PASSWORD_REQUIRE_UPPERCASE=false
VITE_PASSWORD_REQUIRE_NUMBERS=false
VITE_PASSWORD_REQUIRE_SPECIAL_CHARS=false
VITE_USER_NAVIGATION_STYLE=sidebar
VITE_HOME_SIDEBAR_COLLAPSED=false
VITE_SIDEBAR_COLLAPSIBLE_STYLE=icon
VITE_ENABLE_SIDEBAR_TRIGGER=true
VariableOptionsDefaultDescription
VITE_USER_NAVIGATION_STYLEsidebar, headersidebarApp navigation layout (personal + team)
VITE_HOME_SIDEBAR_COLLAPSEDtrue, falsefalseStart collapsed
VITE_SIDEBAR_COLLAPSIBLE_STYLEoffcanvas, icon, noneiconCollapse behavior
VITE_ENABLE_SIDEBAR_TRIGGERtrue, falsetrueShow collapse button

Feature Flags

VITE_ACCOUNT_MODE=hybrid
VITE_ENABLE_THEME_TOGGLE=true
VITE_ENABLE_PERSONAL_ACCOUNT_DELETION=false
VITE_ENABLE_PERSONAL_ACCOUNT_BILLING=false
VITE_ENABLE_TEAM_ACCOUNTS_CREATION=true
VITE_ENABLE_TEAM_ACCOUNTS_DELETION=false
VITE_ENABLE_TEAM_ACCOUNTS_BILLING=false
VITE_ENABLE_NOTIFICATIONS=true
VITE_REALTIME_NOTIFICATIONS=false
VITE_ENABLE_VERSION_UPDATER=false
VITE_LANGUAGE_PRIORITY=application
VariableDefaultDescription
VITE_ACCOUNT_MODEhybridpersonal-only | organizations-only | hybrid. Single control for which account surfaces exist; the team-account flags below are derived from and gated by it.
VITE_ENABLE_PERSONAL_ACCOUNT_DELETIONfalseUsers can delete accounts
VITE_ENABLE_PERSONAL_ACCOUNT_BILLINGfalsePersonal subscription billing
VITE_ENABLE_TEAM_ACCOUNTS_CREATIONtrueUsers can create teams
VITE_ENABLE_TEAM_ACCOUNTS_DELETIONfalseUsers can delete teams
VITE_ENABLE_TEAM_ACCOUNTS_BILLINGfalseTeam subscription billing
VITE_ENABLE_NOTIFICATIONStrueIn-app notifications
VITE_REALTIME_NOTIFICATIONSfalseLive notification updates
VITE_ENABLE_VERSION_UPDATERfalseCheck for updates
VITE_LANGUAGE_PRIORITYapplicationuser or application

Billing Configuration

Provider Selection

VITE_BILLING_PROVIDER=stripe

Options: stripe or lemon-squeezy

Stripe

VITE_STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
VariableRequiredDescription
VITE_STRIPE_PUBLISHABLE_KEYYes (Stripe)Publishable key
STRIPE_SECRET_KEYYes (Stripe)Secret key
STRIPE_WEBHOOK_SECRETYes (Stripe)Webhook signing secret

Lemon Squeezy

LEMON_SQUEEZY_SECRET_KEY=your-secret-key
LEMON_SQUEEZY_STORE_ID=your-store-id
LEMON_SQUEEZY_SIGNING_SECRET=your-signing-secret
VariableRequiredDescription
LEMON_SQUEEZY_SECRET_KEYYes (LS)API secret key
LEMON_SQUEEZY_STORE_IDYes (LS)Store identifier
LEMON_SQUEEZY_SIGNING_SECRETYes (LS)Webhook signing secret

Email Configuration

Provider Selection

MAILER_PROVIDER=nodemailer

Options: nodemailer or resend

Common Settings

EMAIL_SENDER="Your App <noreply@yourapp.com>"
CONTACT_EMAIL=contact@yourapp.com

Resend

RESEND_API_KEY=re_...

Nodemailer (SMTP)

EMAIL_HOST=smtp.provider.com
EMAIL_PORT=587
EMAIL_USER=your-username
EMAIL_PASSWORD=your-password
EMAIL_TLS=true

CMS Configuration

Provider Selection

CMS_CLIENT=keystatic

Options: keystatic or wordpress

Keystatic

VITE_KEYSTATIC_STORAGE_KIND=local
VITE_KEYSTATIC_CONTENT_PATH=./content
KEYSTATIC_PATH_PREFIX=apps/web

For GitHub storage:

VITE_KEYSTATIC_STORAGE_KIND=github
VITE_KEYSTATIC_STORAGE_REPO=owner/repo
KEYSTATIC_GITHUB_TOKEN=github_pat_...
VariableOptionsDescription
VITE_KEYSTATIC_STORAGE_KINDlocal, cloud, githubStorage backend
VITE_KEYSTATIC_CONTENT_PATHPathContent directory
KEYSTATIC_PATH_PREFIXPathMonorepo prefix
VITE_KEYSTATIC_STORAGE_REPOowner/repoGitHub repository
KEYSTATIC_GITHUB_TOKENTokenGitHub access token

WordPress

WORDPRESS_API_URL=https://your-site.com/wp-json

Security Best Practices

  1. Never commit secrets: Use .env.local for sensitive values
  2. Use CI/CD variables: Store production secrets in your deployment platform
  3. Rotate keys regularly: Especially after team member changes
  4. Validate in production: The kit validates configuration at build time

Common Pitfalls

  1. HTTP in production: VITE_SITE_URL must use https:// in production builds.
  2. Same theme colors: VITE_THEME_COLOR and VITE_THEME_COLOR_DARK must be different.
  3. Missing Supabase keys: The app won't start without valid Supabase credentials.
  4. Forgetting to restart: After changing environment variables, you may need to restart the development server.
  5. Wrong file for secrets: Put secrets in .env.local (git-ignored), not .env (committed).