TurboJet

Environment

Root .env keys shared by marketing and docs.

All apps load env from the repository root (.env / .env.example). Copy .env.example to .env and fill values. Turbo exposes the public URL keys via globalEnv.

Public URLs

KeyLocal defaultUsed by
NEXT_PUBLIC_APP_URLhttp://localhost:3001Leftover package CORS / auth origins (point at marketing)
NEXT_PUBLIC_SAAS_URLhttp://localhost:3001Same as app URL now that the dashboard app is gone
NEXT_PUBLIC_MARKETING_URLhttp://localhost:3001Landing, legal, API, checkout
NEXT_PUBLIC_DOCS_URLhttp://localhost:3002This docs site

NODE_ENV in .env is development for local work. Production builds set NODE_ENV=production in the app build script before dotenv so Next does not inherit development from .env.

Database

KeyNotes
DATABASE_URLPrisma (pooled)
DIRECT_URLPrisma migrate / introspect
POSTGRES_PORTDocker Compose host port

Setup walkthrough: Database.

Auth

KeyNotes
BETTER_AUTH_SECRETAt least 32 characters
BETTER_AUTH_URLBetter Auth base URL
GOOGLE_CLIENT_IDGoogle OAuth (required)
GOOGLE_CLIENT_SECRETGoogle OAuth (required)
GITHUB_CLIENT_IDGitHub OAuth (optional)
GITHUB_CLIENT_SECRETGitHub OAuth (optional)
APPLE_CLIENT_IDApple Sign In Service ID (optional)
APPLE_TEAM_IDApple Team ID (optional)
APPLE_KEY_IDApple Key ID (optional)
APPLE_PRIVATE_KEYApple .p8 private key; use \n for newlines (optional)

Payments and email

KeyNotes
MAYAR_API_KEYMayar dashboard API key
MAYAR_WEBHOOK_SECRETShared secret for {MARKETING_URL}/api/webhooks/mayar
MAYAR_PRODUCT_ID_SOLOMayar payment-link product ID for Solo
MAYAR_PRODUCT_ID_PROMayar payment-link product ID for Pro
MAYAR_PAYMENT_LINK_SOLOHosted checkout URL for Solo
MAYAR_PAYMENT_LINK_PROHosted checkout URL for Pro
RESEND_KEYTransactional email — see Resend
RESEND_EMAIL_DOMAINFrom address (local default [email protected]) — see Mail

Setup walkthrough: Payments, Storefront checkout, and Mail.

Optional

KeyNotes
NEXT_PUBLIC_ENABLE_SENTRYSentry feature flag (false disables) — see Monitoring
NEXT_PUBLIC_SENTRY_DSNSentry DSN (empty disables) — see Sentry
SENTRY_AUTH_TOKENOptional. Source map uploads during build — see Sentry
NEXT_PUBLIC_ENABLE_POSTHOGPostHog feature flag (false disables) — see Analytics
NEXT_PUBLIC_POSTHOG_PROJECT_TOKENPostHog project token (empty disables) — see PostHog
NEXT_PUBLIC_POSTHOG_HOSTPostHog API host (default https://us.i.posthog.com; EU: https://eu.i.posthog.com)
AI_GATEWAY_API_KEYVercel AI Gateway key for @repo/ai chat — see AI
OPENAI_API_KEYReserved for direct OpenAI usage
SMTP_HOST / SMTP_PORTLocal SMTP (Mailpit) — see Mailpit; not wired into sendEmail yet
SMTP_USER / SMTP_PASSOptional SMTP auth for Nodemailer
MAILPIT_URLMailpit web UI (default http://localhost:8025)
S3_REGIONR2 region (usually auto)
S3_BUCKETR2 bucket name
S3_ENDPOINThttps://<ACCOUNT_ID>.r2.cloudflarestorage.com
S3_ACCESS_KEY_IDR2 API token access key
S3_SECRET_ACCESS_KEYR2 API token secret
S3_PUBLIC_URLOptional public base (https://pub-….r2.dev or custom domain) for /api/storage/public

Cloudflare R2 setup

Full walkthrough: Storage and Cloudflare R2.

  1. Create a private R2 bucket and an API token with Object Read & Write.
  2. Set CORS on the bucket so browsers can PUT/GET from your marketing origin (NEXT_PUBLIC_MARKETING_URL), e.g. allow PUT, GET, HEAD and Content-Type.
  3. Keep the bucket private; use short-lived signed URLs from /api/storage. Only set S3_PUBLIC_URL if you intentionally expose objects via r2.dev or a custom domain.

Validated in packages/env (envSchema server-side, clientEnvSchema for NEXT_PUBLIC_* used in the browser).

On this page