Environment Variables
Complete reference for all environment variables.
Required Variables
These variables are required for the application to function:
Database
DATABASE_URL="postgresql://user:password@host/db?sslmode=require"Authentication
BETTER_AUTH_SECRET="at-least-32-characters-random-key"
BETTER_AUTH_URL="http://localhost:3000"Application URL
NEXT_PUBLIC_APP_URL="http://localhost:3000"Service Integrations
GRS AI (cursor-generator pipeline)
Required for the main cursor-generator image-to-image pipeline:
GRSAI_API_KEY="sk-your-grsai-key"
GRSAI_API_HOST="https://grsai.dakka.com.cn"Volcano Engine (demo routes only)
Optional. Only used by the demo pages under app/[locale]/demo/ and the
demo API routes (/api/chat, /api/image/generate, /api/video/*).
The main cursor-generator product does not use Volcano Engine — it
uses GRS AI (see above). Skip these env vars if you are not shipping
the demo pages.
# VOLCANO_ENGINE_API_KEY="your-volcano-engine-api-key"
# VOLCANO_ENGINE_API_URL="https://ark.cn-beijing.volces.com/api/v3"Creem (Payments)
Required for subscriptions and one-time purchases:
CREEM_API_KEY="your-creem-api-key"
CREEM_WEBHOOK_SECRET="whsec_..."For testing without real payments:
CREEM_SIMULATE="true"Resend (Email)
Required for authentication emails and notifications:
RESEND_API_KEY="re_your_api_key"
RESEND_FROM_EMAIL="Your App <[email protected]>"Optional, used by the newsletter subscribe / unsubscribe flow:
RESEND_AUDIENCE_ID="your-resend-audience-id"Google OAuth (Optional)
AUTH_GOOGLE_ID="your-google-client-id"
AUTH_GOOGLE_SECRET="your-google-client-secret"Cron Jobs
CRON_SECRET (Bearer) or CRON_JOBS_USERNAME + CRON_JOBS_PASSWORD
(Basic Auth). At least one pair must be set, or the cron routes will
reject every request. Used by the subscription grant job
(/api/cron/subscription-grants) and any future scheduled job.
# Use this:
CRON_SECRET="your-cron-secret"
# ...or these:
# CRON_JOBS_USERNAME="your_username"
# CRON_JOBS_PASSWORD="your_password"Optional Analytics
NEXT_PUBLIC_POSTHOG_KEY="phc_..."
NEXT_PUBLIC_GOOGLE_ANALYTICS_ID="G-..."
NEXT_PUBLIC_CLARITY_PROJECT_ID="..."Optional Storage (S3-Compatible / Cloudflare R2)
Required if you want generated cursor packs mirrored to your own bucket instead of relying on the provider's URL. R2 is recommended.
STORAGE_ENDPOINT="https://<account-id>.r2.cloudflarestorage.com"
STORAGE_BUCKET_NAME="your-bucket"
STORAGE_REGION="auto"
STORAGE_ACCESS_KEY_ID="..."
STORAGE_SECRET_ACCESS_KEY="..."
STORAGE_PUBLIC_URL="https://<your-public-r2-domain>"Field name is
STORAGE_BUCKET_NAME, notSTORAGE_BUCKET. The codebase usesSTORAGE_BUCKET_NAMEeverywhere; the wrong name silently fails to upload.