BetterStarter logo
BetterStarter
Docs
Quick Start

Go Live

Deploy BetterStarter to production in 2 minutes.

Docs are in beta — content is improving rapidly. Found something missing? Open an issue on GitHub or reach out on Twitter (X).

Deploy early, even before the app is "finished." First deploys are easiest when your app is still simple.

Quick Copy Checklist

Use this as your 2-minute launch checklist:

# 1) Create .env.production locally (gitignored)
cp .env.local .env.production

# 2) Edit .env.production for real production values
APP_BASE_URL=https://yourdomain.com
BETTER_AUTH_URL=https://yourdomain.com
BETTER_AUTH_SECRET=<long-random-secret>
DATABASE_URL=postgres://...

# 2.5) Add all feature-specific vars for enabled integrations
# Example: Stripe, Plunk/email, Google OAuth, analytics, storage, webhooks, etc.

# 3) Copy/import env vars from .env.production into hosting platform

# 4) Run production migration using .env.production
pnpm db:migrate:prod

# 5) Deploy on Vercel/Netlify and smoke test

The four variables above are the minimum for core auth + database. Most production apps need additional variables based on enabled features.

2-Minute Go-Live (One-Page Runbook)

Before You Start (30 seconds)

You need:

  1. App hosting: Vercel (recommended) or Netlify
  2. PostgreSQL: Neon (recommended) or Supabase
  3. Your production domain (example: https://yourdomain.com)

Minute 1 — Configure Production

1) Prepare .env.production as source of truth

Create a production env file locally (it is ignored by git):

cp .env.local .env.production

Then edit .env.production with production values.

2) Add required environment variables in your host dashboard

Copy from .env.production and paste/import into your hosting platform:

APP_BASE_URL=https://yourdomain.com
BETTER_AUTH_URL=https://yourdomain.com
BETTER_AUTH_SECRET=<long-random-secret>
DATABASE_URL=postgres://...

Notes:

  • APP_BASE_URL and BETTER_AUTH_URL should match your final production URL.
  • BETTER_AUTH_SECRET should be a strong random secret.
  • DATABASE_URL must point to your production database (not local).

Then add all variables for every feature you have enabled. Common examples:

  • Payments: Stripe keys + webhook secret
  • Email: Plunk (or your provider) API key + sender values
  • OAuth providers: client ID + client secret per provider (Google, GitHub, etc.)
  • Observability/analytics: provider keys and host URL
  • Storage or third-party APIs: access keys, bucket/region IDs, API secrets

If a feature works locally but fails in production, missing env vars are the most common cause.

3) Run production migrations

Run migration using .env.production:

pnpm db:migrate:prod

This local-file approach is common and fine for early-stage apps.

Preferred long-term workflow: run migrations from CI/CD or your hosting environment with production-only secrets, so production credentials are not handled from developer machines.

Minute 2 — Deploy and Verify

5) Deploy

Use the full platform guide if needed:

BetterStarter already includes vercel.json and netlify.toml, so both platforms can deploy with sane defaults.

6) Smoke test after deploy (60 seconds)

Open your production URL and confirm:

  1. Home page loads
  2. Sign up / sign in works
  3. Session persists after refresh
  4. A DB-backed page/action works

If auth fails, double-check that APP_BASE_URL and BETTER_AUTH_URL exactly match the deployed domain (including https).

Fast Troubleshooting

  • Build failed: Recheck required env vars in the host dashboard.
  • Feature works locally but not in production: Verify every feature-specific env var is set in hosting (Stripe/email/OAuth/etc.).
  • Auth callback or cookie issues: URL mismatch between env vars and actual domain.
  • DB connection errors: Wrong DATABASE_URL or blocked network/access rules.
  • Schema errors: Run pnpm db:migrate:prod again and review migration SQL.

After You Go Live (Production DB Workflow)

For all future schema changes:

  1. Edit schema in src/db/schema/
  2. pnpm db:generate to create migration SQL
  3. Review generated SQL in drizzle/
  4. Back up production DB
  5. pnpm db:migrate:prod to apply changes using .env.production

Avoid db:push in production. Use migrations (db:migrate) for safe, auditable changes.

BetterStarter outputs a standard Node.js server and also works on Railway, Render, Fly.io, and Cloudflare Workers.

On this page