React Starter Kit - Deployment & Usage Guide
Prerequisites
- Bun v1.3+ (Install) — Runtime and package manager (replaces Node.js/npm)
- Git — Version control
- Cloudflare account — Required for Workers deployment and edge hosting
- Neon PostgreSQL — Serverless Postgres database (Sign up)
- VS Code (recommended) — With recommended extensions pre-configured
- Optional but recommended:
- Stripe account — For subscription billing (Starter/Pro plans)
- Google Cloud Console — For Google OAuth authentication
- Resend account — For transactional email (OTP, verification, password reset)
Installation
-
Generate from template (or clone directly):
git clone https://github.com/your-username/your-project-name.git cd your-project-name -
Install dependencies:
bun install -
Verify installation:
bun --version # Should be v1.3 or higher
Configuration
1. Environment Variables
Create .env.local (gitignored) or modify .env (committed defaults) in the project root. Required variables based on the stack:
Core Application:
# Application
ENVIRONMENT=development
APP_NAME=YourAppName
APP_ORIGIN=http://localhost:3000
# Database (Neon PostgreSQL)
DATABASE_URL=postgresql://user:password@ep-xxx.us-east-1.aws.neon.tech/dbname
# Authentication (Better Auth)
BETTER_AUTH_SECRET=your-random-secret-min-32-chars
OAuth (Optional):
GOOGLE_CLIENT_ID=xxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=xxx
Email (Resend):
RESEND_API_KEY=re_xxx
RESEND_EMAIL_FROM=onboarding@yourdomain.com
Billing (Stripe - Optional):
STRIPE_SECRET_KEY=sk_test_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx
STRIPE_STARTER_PRICE_ID=price_xxx
STRIPE_PRO_PRICE_ID=price_xxx
STRIPE_PRO_ANNUAL_PRICE_ID=price_xxx
2. Database Setup
-
Create Neon PostgreSQL database and copy the connection string to
DATABASE_URL -
Run migrations:
cd db bun run db:migrate -
Seed data (if available):
bun run db:seed
3. Authentication Configuration
The auth system (apps/api/lib/auth.ts) supports:
- Email OTP: Requires
RESEND_API_KEYandRESEND_EMAIL_FROM - Passkey: Works out of the box
- Google OAuth: Requires
GOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRET - Organizations: Enabled by default via Better Auth
- Stripe Billing: Only enabled when all Stripe env vars are present
4. Configure Service Bindings (Local Development)
For local development with Cloudflare Workers service bindings, create wrangler.toml files in apps/web, apps/app, and apps/api if not present. The web worker proxies /api/* to the API worker and app routes to the app worker.
Build & Run
Development Mode
Run all apps simultaneously (from root):
bun run dev
Or run individually:
# API server (Hono + tRPC)
cd apps/api && bun run dev
# React SPA (TanStack Router)
cd apps/app && bun run dev
# Marketing site (Astro)
cd apps/web && bun run dev
# Email templates
cd apps/email && bun run dev
Database Operations
# Generate migrations after schema changes
cd db && bun run db:generate
# Push schema changes (development only)
bun run db:push
# Studio (Drizzle ORM GUI)
bun run db:studio
Production Build
# Build all apps
bun run build
# Type checking
bun run typecheck
# Linting
bun run lint
# Testing
bun run test
Deployment
This stack deploys to Cloudflare Workers with three separate workers (web, app, api) connected via service bindings.
1. Initial Cloudflare Setup
-
Install Wrangler CLI:
bun add -g wrangler -
Authenticate:
wrangler login -
Create D1/Database bindings (if using Cloudflare D1 instead of Neon, though Neon is recommended)
2. Terraform Infrastructure (Recommended)
The infra/ directory contains Terraform configurations for Cloudflare Workers, DNS, and Hyperdrive.
cd infra
# Initialize Terraform
terraform init
# Plan deployment
terraform plan
# Apply
terraform apply
Resources created:
- Cloudflare Workers (web, app, api)
- DNS records
- Hyperdrive (database connection pooling for Neon)
- KV namespaces (if needed for caching)
3. Manual Deployment (Alternative)
Deploy each worker individually:
# Deploy API worker first
cd apps/api
wrangler deploy
# Deploy App worker
cd ../app
wrangler deploy
# Deploy Web worker (edge router)
cd ../web
wrangler deploy
4. Environment Variables in Production
Set secrets for each worker:
cd apps/api
wrangler secret put BETTER_AUTH_SECRET
wrangler secret put DATABASE_URL
wrangler secret put STRIPE_SECRET_KEY
# ... repeat for all env vars
Repeat for apps/app and apps/web as needed.
5. Stripe Webhook Configuration
Configure Stripe webhook endpoint to point to your deployed API worker:
https://api.yourdomain.com/api/auth/stripe/webhook
Events to listen for:
customer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedinvoice.payment_succeededinvoice.payment_failed
Troubleshooting
Bun Runtime Issues
Error: bun: command not found
- Ensure Bun v1.3+ is installed:
curl -fsSL https://bun.sh/install | bash - Restart terminal after installation
Error: Cannot find module in monorepo
- Run
bun installfrom root, not individual app directories - Bun workspaces require installation at root level
Database Connection Failures
Error: connection refused or SSL errors
- Verify
DATABASE_URLincludes SSL parameters:?sslmode=require - For local development without SSL, use
?sslmode=disable(not recommended for production) - Ensure Neon database allows connections from your IP (or use
0.0.0.0/0for development)
Migration errors
- Ensure you're running commands from the
db/directory or usingbun runscripts from root - Check that
drizzle-ormanddrizzle-kitare installed:bun installindb/directory
Authentication Issues
Email OTP not sending
- Verify
RESEND_API_KEYis set and valid - Check
RESEND_EMAIL_FROMuses a verified domain in Resend - Review API worker logs:
wrangler tailinapps/api
Google OAuth redirect errors
- Ensure
APP_ORIGINmatches exactly (including protocol and port) - Add authorized redirect URI in Google Cloud Console:
https://api.yourdomain.com/api/auth/callback/google
"Auth hint cookie" warnings
- This is normal; the
__Host-auth_hintcookie is for edge routing optimization, not security - In HTTP dev mode, the cookie name drops the
__Host-prefix automatically
Cloudflare Workers Deployment
Service binding errors
- Deploy API worker before Web worker (Web depends on API service binding)
- Check
wrangler.tomlservice bindings match worker names exactly
Environment variables not loading
- Local dev uses
.envfiles; production requireswrangler secret put - Verify
ENVIRONMENTvariable is set toproductionin deployed workers
Cold start latency
- First request to Neon database may be slow; Hyperdrive (configured in
infra/) mitigates this - Consider enabling Cloudflare's Always Online or warming endpoints
Build Errors
TypeScript errors in routeTree.gen.ts
- This file is auto-generated by TanStack Router; do not edit manually
- Run
bun run devinapps/appto regenerate, or delete the file and restart dev server
Tailwind CSS v4 issues
- Ensure VS Code extension is updated for Tailwind v4
- Check
apps/app/app.cssuses the new v4 import syntax:@import "tailwindcss"
Stripe Integration
Webhook signature verification fails
- Ensure
STRIPE_WEBHOOK_SECRETis the webhook signing secret, not the API key - Verify webhook endpoint URL is correct and publicly accessible (use ngrok for local testing)
Billing endpoints return 404
- This is expected behavior when Stripe env vars are missing; the plugin only loads when all required variables are present
- Check
apps/api/lib/auth.tsfor the conditional Stripe plugin loading logic