Documentation

Environment Variables

Required and optional environment variables for Motoko Base — database, auth, billing, email, storage, analytics, monitoring, and AI.

Open inChatGPT (opens in a new tab)Claude (opens in a new tab)Cursor (opens in a new tab)Required and optional environment variables for Motoko Base — database, auth, billing, email, storage, analytics, monitoring, and AI.

Motoko Base reads configuration from environment variables. Copy .env.example to .env or .env.local and fill in values:

cp .env.example .env

Never commit real secrets. .env* is gitignored except .env.example. Never put server-only secrets on NEXT_PUBLIC_* — those are exposed to the browser.

Optional integrations soft-fail when unset: the app boots, unrelated routes keep working, and feature pages show a clear configuration message instead of crashing.

Required

These three variables are enough to start the dev server and run migrations:

VariableRequiredPurpose
DATABASE_URLYesPostgreSQL connection string (server-only)
BETTER_AUTH_SECRETYesSigning secret for sessions and tokens
BETTER_AUTH_URLYesPublic origin for auth callbacks — use http://localhost:3000 locally

Generate a secret:

openssl rand -base64 32

Email verification is required before dashboard access. Without Resend configured, you can start the app but you will not receive verification emails after sign-up.

VariableRequiredPurpose
RESEND_API_KEYRecommendedResend API key for transactional email
EMAIL_FROMRecommendedSender address, e.g. Motoko Base <onboarding@resend.dev> for Resend onboarding tests

Application

VariableRequiredPurpose
NEXT_PUBLIC_APP_URLNoPublic app origin for short links (/r/{slug}) and password-reset redirects. Falls back to the request origin when unset. Keep aligned with BETTER_AUTH_URL in production.

Authentication

VariableRequiredPurpose
BETTER_AUTH_SECRETYesSession and token signing secret
BETTER_AUTH_URLYesCanonical auth origin (must match the URL users hit for callbacks)
BETTER_AUTH_TRUSTED_ORIGINSNoComma-separated extra origins for preview/staging hosts
GOOGLE_CLIENT_IDNoGoogle OAuth client ID — leave unset to disable Google sign-in
GOOGLE_CLIENT_SECRETNoGoogle OAuth client secret
GITHUB_CLIENT_IDNoGitHub OAuth app client ID — leave unset to disable GitHub sign-in
GITHUB_CLIENT_SECRETNoGitHub OAuth app client secret

OAuth callback URLs must match BETTER_AUTH_URL:

  • Google: {BETTER_AUTH_URL}/api/auth/callback/google
  • GitHub: {BETTER_AUTH_URL}/api/auth/callback/github

Database

VariableRequiredPurpose
DATABASE_URLYesPostgreSQL connection string (Supabase or local). Never NEXT_PUBLIC_*.

For Supabase at runtime, prefer the transaction pooler (often port 6543). If migrations fail through the pooler, temporarily point DATABASE_URL at the direct connection (often port 5432). See src/lib/db/README.md.

Billing

VariableRequiredPurpose
BILLING_PROVIDERNoBilling provider selection (polar in v1). Defaults to polar.
POLAR_ACCESS_TOKENNoPolar Organization Access Token — leave unset to stay on Free
POLAR_WEBHOOK_SECRETNoWebhook secret from Polar → Settings → Webhooks
POLAR_PRO_MONTHLY_PRODUCT_IDNoPro monthly product ID from Polar Dashboard
POLAR_PRO_YEARLY_PRODUCT_IDNoPro yearly product ID (optional)
POLAR_GROWTH_MONTHLY_PRODUCT_IDNoGrowth monthly product ID (optional)
POLAR_GROWTH_YEARLY_PRODUCT_IDNoGrowth yearly product ID (optional)
POLAR_SCALE_MONTHLY_PRODUCT_IDNoScale monthly product ID (optional)
POLAR_SCALE_YEARLY_PRODUCT_IDNoScale yearly product ID (optional)
POLAR_SERVERNosandbox or production (tokens and products are environment-specific)

Use the {PLAN}_{MONTHLY|YEARLY}_PRODUCT_ID pattern as the canonical names (matching .env.example). Legacy aliases such as POLAR_PRO_PRODUCT_ID remain supported at runtime for backward compatibility — see comments in .env.example and src/lib/billing/providers/polar/product-map.ts.

Webhook endpoint: {APP_URL}/api/billing/webhooks/polar

Email

VariableRequiredPurpose
RESEND_API_KEYNo*Resend API key (server-only)
EMAIL_FROMNo*Single sender identity, e.g. Motoko Base <noreply@yourdomain.com>

* Both are needed for email delivery. The app boots without them, but signup verification will not work.

Storage

Cloudflare R2 powers the File Storage demo and avatar uploads. Leave unset to boot without Storage.

VariableRequiredPurpose
R2_ACCOUNT_IDNoCloudflare account ID (used to build the S3 API endpoint)
R2_ACCESS_KEY_IDNoR2 API token access key
R2_SECRET_ACCESS_KEYNoR2 API token secret
R2_BUCKET_NAMENoPrivate bucket name. A slash is treated as an object-key prefix: my-bucket/demo → bucket my-bucket, prefix demo/
R2_PREFIXNoOptional explicit object-key prefix (overrides a slash suffix on the bucket name)
R2_ENDPOINTNoOptional S3 API endpoint override (defaults from R2_ACCOUNT_ID)

Analytics

PostHog is split into client capture (project token) and server HogQL queries (personal API key).

VariableRequiredPurpose
NEXT_PUBLIC_POSTHOG_PROJECT_TOKENNoPostHog project API key for client capture
NEXT_PUBLIC_POSTHOG_HOSTNoIngest host (US default: https://us.i.posthog.com, EU: https://eu.i.posthog.com)
POSTHOG_PERSONAL_API_KEYNoPersonal API key with Query Read — used by /dashboard/analytics
POSTHOG_PROJECT_IDNoPostHog project ID for HogQL queries
POSTHOG_HOSTNoApp API host for Query API (US: https://us.posthog.com, EU: https://eu.posthog.com)

Monitoring

VariableRequiredPurpose
NEXT_PUBLIC_SENTRY_DSNNoPublic Sentry DSN — leave unset to disable monitoring
SENTRY_AUTH_TOKENNoAuth token for source map upload during next build
SENTRY_ORGNoSentry organization slug
SENTRY_PROJECTNoSentry project slug

Sentry is also disabled automatically during next dev (even if DSN is set) to avoid webpack listener noise.

AI

VariableRequiredPurpose
OPENAI_API_KEYNoOpenAI or compatible API key — leave unset to disable AI Email demo
OPENAI_BASE_URLNoOptional OpenAI-compatible API base URL
OPENAI_MODELNoModel ID (defaults to gpt-4o-mini)

Quick reference by boot requirement

CategoryMinimal bootFull feature set
DatabaseDATABASE_URLDATABASE_URL
AuthenticationBETTER_AUTH_SECRET, BETTER_AUTH_URL+ optional OAuth vars
Email—RESEND_API_KEY, EMAIL_FROM
Billing—POLAR_* vars
Storage—R2_* vars
Analytics—PostHog vars
Monitoring—Sentry vars
AI—OPENAI_API_KEY

See .env.example for inline comments on every variable.


Next steps

Configuration — Where config files live and how to change navigation, billing plans, metadata, and integrations.