Environment Variables
Copy the local environment example and look up required, public, and server-only values.
Configure your local app with the values generated by ./coremvp env sync, then
add the provider settings for the capabilities you use.
Local environment
Polar billing settings
Follow Polar Billing for the sandbox sequence.
All settings below are server-only; do not add a NEXT_PUBLIC_ prefix.
| Setting | Default / purpose |
|---|---|
PAYMENT_PROVIDER | stripe; use polar for new lifetime and recurring checkout. Existing relationships keep their own provider. |
POLAR_ENVIRONMENT | sandbox; selects the Polar environment read for lifetime/subscription access and management. Switching to production excludes sandbox grants and targets without deleting history. Independent of PAYMENT_PROVIDER. |
POLAR_ORGANIZATION_ID | Organization owning the configured offers. |
POLAR_INDIVIDUAL_PRODUCT_ID, POLAR_TEAM_PRODUCT_ID | Fixed one-time offers for the source lifetime tiers. |
POLAR_STARTER_PRODUCT_ID_MONTHLY, POLAR_STARTER_PRODUCT_ID_YEARLY | Starter monthly/yearly fixed recurring products. |
POLAR_PRO_PRODUCT_ID_MONTHLY, POLAR_PRO_PRODUCT_ID_YEARLY | Pro monthly/yearly fixed recurring products. |
POLAR_BUSINESS_PRODUCT_ID_MONTHLY, POLAR_BUSINESS_PRODUCT_ID_YEARLY | Business monthly/yearly fixed recurring products. |
POLAR_ACCESS_TOKEN | Runtime organization token with checkouts:write, products:read, orders:read, subscriptions:read and customer_sessions:write. Catalog/lifecycle administration uses operator permissions separately. |
POLAR_WEBHOOK_SECRET | Signing secret for this endpoint/listener. |
POLAR_TEST_EMAIL | Optional organization-member mailbox used by the local guest sandbox test. |
POLAR_TEST_DISCOUNT_CODE | Optional configured discount for the local hosted checkout proof. |
POLAR_TEST_BILLING_COUNTRY | Local proof address: United States by default, or United Kingdom. |
The existing Stripe settings remain necessary for Stripe subscriptions, retained customer portal sessions and outstanding Stripe event processing. A Polar-only app can omit them.
Run ./coremvp env sync after local Supabase starts. The CLI writes the local
app URL, Supabase URL, publishable key, secret key, and database connection to
.env.local. Do not copy those values from another checkout or maintain them
by hand.
Local OAuth is optional and has a separate startup prerequisite. To test Google,
follow Configure OAuth Providers
before starting Supabase. env sync derives app connection values; it does not
configure OAuth providers or supply their client credentials.
Inspect redacted env
Check redacted env presence with:
./coremvp env listUse this command for troubleshooting because it reports set or missing without printing secret values.
Key presence does not prove connectivity. Start your app and follow the local Auth checks to check the running application.
Local env example
This block shows shared application settings and the default Stripe provider.
Keep the Supabase and database values written by env sync. For Polar, omit
the Stripe sections and add the Polar settings instead.
For Stripe, add your test keys and replace every prod_replace_me and
price_replace_me for the tiers you sell.
For Stripe, lifetime billing uses the four Individual/Team ID variables; subscriptions use
the nine Starter/Pro/Business ID variables. Configure the tiers you use from
src/config/pricing.config.ts.
# App origin
NEXT_PUBLIC_APP_URL=http://localhost:3000
# Supabase Auth and database
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=...
SUPABASE_SECRET_KEY=...
DATABASE_URL=postgresql://postgres:<password>@127.0.0.1:54322/postgres
# Stripe settings shared by lifetime and subscription billing
NEXT_PUBLIC_STRIPE_MODE=test
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
# Lifetime billing IDs: Individual and Team (one-time payments)
# Optional: configure only the lifetime offers you sell.
# Individual
NEXT_PUBLIC_STRIPE_INDIVIDUAL_PRODUCT_ID=prod_replace_me
NEXT_PUBLIC_STRIPE_INDIVIDUAL_PRICE_ID=price_replace_me
# Team
NEXT_PUBLIC_STRIPE_TEAM_PRODUCT_ID=prod_replace_me
NEXT_PUBLIC_STRIPE_TEAM_PRICE_ID=price_replace_me
# Subscription billing IDs: Starter, Pro, and Business (monthly/yearly)
# Optional: configure only the subscription offers and cadences you sell.
# Starter
NEXT_PUBLIC_STRIPE_STARTER_PRODUCT_ID=prod_replace_me
NEXT_PUBLIC_STRIPE_STARTER_PRICE_ID_MONTHLY=price_replace_me
NEXT_PUBLIC_STRIPE_STARTER_PRICE_ID_YEARLY=price_replace_me
# Pro
NEXT_PUBLIC_STRIPE_PRO_PRODUCT_ID=prod_replace_me
NEXT_PUBLIC_STRIPE_PRO_PRICE_ID_MONTHLY=price_replace_me
NEXT_PUBLIC_STRIPE_PRO_PRICE_ID_YEARLY=price_replace_me
# Business
NEXT_PUBLIC_STRIPE_BUSINESS_PRODUCT_ID=prod_replace_me
NEXT_PUBLIC_STRIPE_BUSINESS_PRICE_ID_MONTHLY=price_replace_me
NEXT_PUBLIC_STRIPE_BUSINESS_PRICE_ID_YEARLY=price_replace_me
# Email delivery
EMAIL_DELIVERY_MODE=mock
# Optional: hosted email capture tests
# TEST_EMAIL_CAPTURE_TOKEN=... # only for test_capture
# Optional: real email delivery
# RESEND_API_KEY=... # only for real email
# RESEND_FROM_EMAIL=onboarding@example.com # only for real emailLocal variables
App and Supabase
| Variable | Required locally | Runtime | Description |
|---|---|---|---|
NEXT_PUBLIC_APP_URL | Yes | Browser/server | Local app origin, usually http://localhost:3000. |
NEXT_PUBLIC_SUPABASE_URL | Yes | Browser/server | Local Supabase API URL from bunx supabase status. |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY | Yes | Browser/server | Local Supabase publishable key generated by ./coremvp env sync. |
SUPABASE_SECRET_KEY | Yes (generated) | Server only | Local Supabase secret key generated by ./coremvp env sync; never expose it to browser code. |
DATABASE_URL | Yes | Server only | Local Supabase Postgres connection string. |
Shared Stripe settings
These entries apply when using Stripe. Keep them for retained Stripe billing
even when PAYMENT_PROVIDER=polar selects new checkout.
| Variable | Required locally | Runtime | Description |
|---|---|---|---|
NEXT_PUBLIC_STRIPE_MODE | No; defaults to test | Browser/server | Selects test or live independently of NODE_ENV. Use test locally. |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | Billing only | Browser/server | Stripe test publishable key for checkout UI. |
STRIPE_SECRET_KEY | Billing only | Server only | Stripe test secret key for checkout and billing routes. |
STRIPE_WEBHOOK_SECRET | Webhooks only | Server only | Stripe CLI webhook secret from stripe listen --forward-to localhost:3000/api/webhooks/stripe. |
STRIPE_SECRET_KEY_LIVE | No | Server only | Optional live-mode key override; ignored when the selected mode is test. |
Lifetime billing IDs
| Variable | Required locally | Runtime | Description |
|---|---|---|---|
NEXT_PUBLIC_STRIPE_INDIVIDUAL_PRODUCT_ID | Own test catalog | Browser/server | Individual Product ID from your Stripe test account. |
NEXT_PUBLIC_STRIPE_INDIVIDUAL_PRICE_ID | Own test catalog | Browser/server | Individual one-time Price ID from your Stripe test account. |
NEXT_PUBLIC_STRIPE_TEAM_PRODUCT_ID | Own test catalog | Browser/server | Team Product ID from your Stripe test account. |
NEXT_PUBLIC_STRIPE_TEAM_PRICE_ID | Own test catalog | Browser/server | Team one-time Price ID from your Stripe test account. |
Subscription billing IDs
| Variable | Required locally | Runtime | Description |
|---|---|---|---|
NEXT_PUBLIC_STRIPE_STARTER_PRODUCT_ID | Own test catalog | Browser/server | Starter Product ID from your Stripe test account. |
NEXT_PUBLIC_STRIPE_STARTER_PRICE_ID_MONTHLY | Own test catalog | Browser/server | Starter monthly Price ID from your Stripe test account. |
NEXT_PUBLIC_STRIPE_STARTER_PRICE_ID_YEARLY | Own test catalog | Browser/server | Starter yearly Price ID from your Stripe test account. |
NEXT_PUBLIC_STRIPE_PRO_PRODUCT_ID | Own test catalog | Browser/server | Pro Product ID from your Stripe test account. |
NEXT_PUBLIC_STRIPE_PRO_PRICE_ID_MONTHLY | Own test catalog | Browser/server | Pro monthly Price ID from your Stripe test account. |
NEXT_PUBLIC_STRIPE_PRO_PRICE_ID_YEARLY | Own test catalog | Browser/server | Pro yearly Price ID from your Stripe test account. |
NEXT_PUBLIC_STRIPE_BUSINESS_PRODUCT_ID | Own test catalog | Browser/server | Business Product ID from your Stripe test account. |
NEXT_PUBLIC_STRIPE_BUSINESS_PRICE_ID_MONTHLY | Own test catalog | Browser/server | Business monthly Price ID from your Stripe test account. |
NEXT_PUBLIC_STRIPE_BUSINESS_PRICE_ID_YEARLY | Own test catalog | Browser/server | Business yearly Price ID from your Stripe test account. |
Email delivery
| Variable | Required locally | Runtime | Description |
|---|---|---|---|
EMAIL_DELIVERY_MODE | No | Server only | Use mock for the normal local path. Use real only when you intentionally want local code to send real email. See Email Testing. |
TEST_EMAIL_CAPTURE_TOKEN | Test capture only | Server only | Secret token for hosted capture lookup. Not needed for the normal local path. |
RESEND_API_KEY | Real email only | Server only | Resend API key when EMAIL_DELIVERY_MODE=real. This can work locally, but it sends real email and is not part of first-run billing setup. |
RESEND_FROM_EMAIL | Real email only | Server only | Sender address when EMAIL_DELIVERY_MODE=real. |
Stripe catalog
Use your own Stripe test account's Product and Price IDs. IDs come only from environment settings. You can start the app without test IDs; checkout stays unavailable for any Price ID you have not configured. Both test and live mode accept a partial catalog. Configure Price IDs only for the offers you sell; other offers remain unavailable. Supplied Product IDs are validated when that offer is used.
Shared pricing contains presentation only. Stripe offer lookup and legacy
Price authorization live in src/config/stripe-catalog.ts.
Keep displayed amounts and features in src/config/pricing.config.ts aligned
with Stripe. The server requires a secret key matching the selected mode.
Restart bun run dev after local catalog changes.
Production environment
Preview and Production use the same variable names with environment-specific values. See Hosted Environment Variables for the shared copyable block and hosted requirements.
Security rules
| Rule | Reason |
|---|---|
Never commit .env or .env.local | These files contain secrets. |
Never expose server keys as NEXT_PUBLIC_* | Browser bundles can read public variables. |
| Do not print setup links or secret values | Keeps test artifacts safe for sharing. |
What's next
Run Locally
Start the app with the configured local values.
Choose mock, hosted capture, or real email delivery.
Deployment
Copy the shared Preview and Production inputs.
Was this page helpful?