← Back to kriasoft/react-starter-kit

How to Deploy & Use kriasoft/react-starter-kit

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

  1. Generate from template (or clone directly):

    git clone https://github.com/your-username/your-project-name.git
    cd your-project-name
    
  2. Install dependencies:

    bun install
    
  3. 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

  1. Create Neon PostgreSQL database and copy the connection string to DATABASE_URL

  2. Run migrations:

    cd db
    bun run db:migrate
    
  3. 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_KEY and RESEND_EMAIL_FROM
  • Passkey: Works out of the box
  • Google OAuth: Requires GOOGLE_CLIENT_ID and GOOGLE_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

  1. Install Wrangler CLI:

    bun add -g wrangler
    
  2. Authenticate:

    wrangler login
    
  3. 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.created
  • customer.subscription.updated
  • customer.subscription.deleted
  • invoice.payment_succeeded
  • invoice.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 install from root, not individual app directories
  • Bun workspaces require installation at root level

Database Connection Failures

Error: connection refused or SSL errors

  • Verify DATABASE_URL includes 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/0 for development)

Migration errors

  • Ensure you're running commands from the db/ directory or using bun run scripts from root
  • Check that drizzle-orm and drizzle-kit are installed: bun install in db/ directory

Authentication Issues

Email OTP not sending

  • Verify RESEND_API_KEY is set and valid
  • Check RESEND_EMAIL_FROM uses a verified domain in Resend
  • Review API worker logs: wrangler tail in apps/api

Google OAuth redirect errors

  • Ensure APP_ORIGIN matches 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_hint cookie 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.toml service bindings match worker names exactly

Environment variables not loading

  • Local dev uses .env files; production requires wrangler secret put
  • Verify ENVIRONMENT variable is set to production in 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 dev in apps/app to 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.css uses the new v4 import syntax: @import "tailwindcss"

Stripe Integration

Webhook signature verification fails

  • Ensure STRIPE_WEBHOOK_SECRET is 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.ts for the conditional Stripe plugin loading logic