saas-starter Svelte Themes

Saas Starter

SaaS starter kit built for humans with agentic workflows. SvelteKit, Convex, BetterAuth and full-stack type safety. Scaffold admin panels and production backends with ease.

SaaS Starter

A full-stack SaaS starter template built with SvelteKit, Convex, and modern web technologies.

Features

  • ๐Ÿ” Authentication - Complete auth system with OAuth (Google) and email/password
  • ๐Ÿ“ง Email System - Production-ready email delivery with Resend (queuing, durability, tracking)
  • ๐Ÿ’ฌ Real-time Chat - Demo chat application with live messaging
  • ๐ŸŽจ Modern UI - Tailwind CSS + Skeleton UI components
  • โšก Fast Backend - Convex for real-time data and serverless functions
  • ๐Ÿงช Testing - E2E testing with Playwright and unit tests with Vitest
  • ๐Ÿ“ฑ Responsive - Mobile-first design
  • ๐Ÿ”ง Developer Experience - TypeScript, ESLint, Prettier, Husky

Tech Stack

  • Frontend: SvelteKit, Svelte 5, Tailwind CSS, Skeleton UI
  • Backend: Convex (real-time database + serverless functions)
  • Authentication: Convex Auth with OAuth providers
  • Testing: Playwright (E2E), Vitest (unit)
  • Development: TypeScript, ESLint, Prettier, Husky

Quick Start

1. Clone and Install

git clone <your-repo-url>
cd saas-starter
bun install

2. Set up Convex

# Initialize Convex project
bunx convex dev

3. Environment Variables

Create .env.local:

CONVEX_DEPLOYMENT=your-deployment-name
PUBLIC_CONVEX_URL=https://your-deployment-name.convex.cloud

4. OAuth Providers (Optional)

Google OAuth Setup

  1. Create a Google OAuth app in the Google Cloud Console
  2. Set callback URL: https://[your-deployment-name].convex.site/api/auth/callback/google
  3. Set environment variables:
bunx convex env set AUTH_GOOGLE_ID your_google_client_id
bunx convex env set AUTH_GOOGLE_SECRET your_google_client_secret

5. Email Configuration (Required for Auth)

This project uses Resend for production-ready email delivery.

Setup Resend

  1. Create a Resend account at resend.com
  2. Get your API key from the Resend dashboard
  3. Verify your domain (or use [email protected] for testing)

Configure Environment Variables

# Set your Resend API key
bunx convex env set RESEND_API_KEY re_xxxxxxxxxxxx

# Set your sender email address
bunx convex env set AUTH_EMAIL "[email protected]"

For testing: You can use [email protected] as your sender while in development.

Email Features

  • โœ… Automatic Queuing - Reliably handles email delivery
  • โœ… Durable Execution - Survives server restarts
  • โœ… Idempotency - Prevents duplicate sends
  • โœ… Event Tracking - Track deliveries, bounces, spam complaints
  • โœ… Test Mode - Safe development with delivery restrictions

Webhook Setup (Optional)

For email event tracking (delivery confirmations, bounces, etc.):

  1. Go to your Resend dashboard โ†’ Webhooks
  2. Add a new webhook endpoint:
    https://your-deployment-name.convex.site/resend-webhook
    
  3. Select events to track (delivered, bounced, complained, etc.)
  4. Copy the webhook signing secret
  5. Set the secret in Convex:
    bunx convex env set RESEND_WEBHOOK_SECRET whsec_xxxxxxxxxxxx
    

6. Run Development Server

bun run dev

Visit http://localhost:5173 to see your app!

7. Set Up First Admin (Required for Admin Panel)

The admin panel requires at least one admin user. To promote your first admin:

  1. Sign up with the email you want to be admin

  2. Run the seed command:

    bunx convex run admin/mutations:seedFirstAdmin '{"email":"[email protected]"}'
    

This is a one-time setup. The command will:

  • Verify the user exists
  • Check that no admins exist yet (prevents accidental re-runs)
  • Promote the user to admin role
  • Enable notification preferences for admin alerts

Note: After the first admin is set up, additional admins can be promoted via the Admin Panel โ†’ Users page.

8. Sync Existing Admins (Migration)

If you had admin users before the notification preferences feature was added, run this one-time migration to sync them:

bunx convex run admin/notificationPreferences/mutations:syncAllAdminPreferences

This ensures all existing admins appear in the Admin Settings โ†’ Notification Recipients page. Safe to run multiple times.

Available Scripts

  • bun run dev - Start development server
  • bun run build - Build for production
  • bun run preview - Preview production build
  • bun run test - Run all tests (E2E + unit)
  • bun run test:e2e - Run E2E tests only
  • bun run test:unit - Run unit tests only
  • bun run lint - Lint code
  • bun run format - Format code

Project Structure

src/
โ”œโ”€โ”€ lib/
โ”‚   โ”œโ”€โ”€ convex/          # Convex backend functions and schema
โ”‚   โ”œโ”€โ”€ demo/            # Demo chat application components
โ”‚   โ”œโ”€โ”€ svelte/          # Svelte auth components
โ”‚   โ””โ”€โ”€ sveltekit/       # SvelteKit auth utilities
โ”œโ”€โ”€ routes/
โ”‚   โ”œโ”€โ”€ +layout.svelte   # Root layout with auth setup
โ”‚   โ”œโ”€โ”€ +page.svelte     # Home page
โ”‚   โ”œโ”€โ”€ product/         # Protected product page
โ”‚   โ””โ”€โ”€ signin/          # Sign-in page
โ””โ”€โ”€ app.html             # HTML template

Authentication

This starter includes a complete authentication system:

  • OAuth Providers: Google (easily extendable to others)
  • Email/Password: Traditional email authentication
  • Route Protection: Protect pages or entire app sections
  • Server-side Auth: Full SSR support with auth state

See SvelteKit Auth Documentation for detailed setup and usage.

Database & Backend

Powered by Convex:

  • Real-time: Automatic live updates
  • Serverless: No server management needed
  • TypeScript: End-to-end type safety
  • Queries & Mutations: Reactive data layer

See Convex Documentation for schema and functions.

Testing

E2E Testing

Setup

  1. Configure test environment variables:

    # Copy the example file
    cp .env.test.example .env.test
    
    # Edit .env.test and ensure it contains:
    # AUTH_E2E_TEST_SECRET=test-secret
    # PUBLIC_E2E_TEST=true
    
  2. Configure Convex backend:

    # Set the test secret in your Convex deployment
    bunx convex env set AUTH_E2E_TEST_SECRET test-secret
    
    # Initialize test data
    bunx convex run tests:init
    
  3. For GitHub Actions (CI/CD):

    • Go to your repository Settings โ†’ Secrets and variables โ†’ Actions
    • Add the following repository secrets:
      • AUTH_E2E_TEST_SECRET: Set to test-secret
      • TEST_CONVEX_URL: Your development Convex URL (for running tests)
      • PUBLIC_CONVEX_URL: Your production Convex URL (for deployment)
    • Tests run against the development environment to keep production clean
    • This is already configured in .github/workflows/quality-checks.yml
  4. Install Playwright and run tests:

    # Install Playwright
    bunx playwright install
    
    # Run tests
    bun run test:e2e
    

Important: The AUTH_E2E_TEST_SECRET must be configured in three places:

  • Local .env.test file (for local development)
  • Convex development backend (for test authentication) - NOT in production
  • GitHub Secrets (for CI/CD)

Note: CI/CD tests run against the development Convex deployment to keep production data clean. The TEST_CONVEX_URL secret points to your development environment while PUBLIC_CONVEX_URL is used for production deployments.

Unit Testing

bun run test:unit

Deployment

Deploy to Vercel

Setup

  1. Get your Convex deployment URL and deploy key:

    • Your Convex URL: Check .env.local for PUBLIC_CONVEX_URL (e.g., https://intent-snake-818.convex.cloud)
    • Generate deploy key: Go to Convex Dashboard โ†’ Settings โ†’ Deploy Keys โ†’ Generate Production Deploy Key
  2. Set environment variables in Vercel:

    Free Tier Setup (using development Convex for previews)

    Without Convex Pro, preview deployments should use your development Convex deployment while production uses your production deployment.

    Using Vercel CLI:

    # Production environment (uses production Convex)
    echo "https://your-prod-deployment.convex.cloud" | vercel env add PUBLIC_CONVEX_URL production
    echo "prod:your-prod-deployment|your-prod-key" | vercel env add CONVEX_DEPLOY_KEY production
    
    # Preview environment (uses development Convex)
    echo "https://your-dev-deployment.convex.cloud" | vercel env add PUBLIC_CONVEX_URL preview
    echo "dev:your-dev-deployment|your-dev-key" | vercel env add CONVEX_DEPLOY_KEY preview
    

    Or via Vercel Dashboard:

    • Go to your project โ†’ Settings โ†’ Environment Variables

    For Production:

    • Add PUBLIC_CONVEX_URL: Your production Convex URL
      • Environment: Production only
    • Add CONVEX_DEPLOY_KEY: Your production deploy key (prod:...)
      • Environment: Production only

    For Preview (PR deployments):

    • Add PUBLIC_CONVEX_URL: Your development Convex URL
      • Environment: Preview only
    • Add CONVEX_DEPLOY_KEY: Your development deploy key (dev:...)
      • Environment: Preview only

    Why this setup?

    • Free tier doesn't support separate preview Convex deployments
    • Preview/PR deployments use your development database (safe for testing)
    • Production deployments use your production database (real data)
    Convex Pro Setup (dedicated preview deployments)

    With Convex Pro, you can create separate preview deployments for each PR.

    Using Vercel CLI:

    # Set production Convex for both environments
    echo "https://your-deployment.convex.cloud" | vercel env add PUBLIC_CONVEX_URL production preview
    echo "prod:your-deployment|your-key" | vercel env add CONVEX_DEPLOY_KEY production preview
    

    Or via Vercel Dashboard:

    • Go to your project โ†’ Settings โ†’ Environment Variables
    • Add PUBLIC_CONVEX_URL: Your production Convex URL
      • Select both "Production" and "Preview" environments
    • Add CONVEX_DEPLOY_KEY: Your production deploy key
      • Select both "Production" and "Preview" environments

    See Convex Preview Deployments for more details.

  3. Configure Build Command:

    โš ๏ธ Important: Override the build command (click to expand)

    Vercel needs to deploy your Convex functions before building SvelteKit to generate the required _generated files.

    Via Vercel Dashboard (Recommended):

    1. Go to your project โ†’ Settings โ†’ General
    2. Scroll to "Framework Settings" โ†’ "Build & Development Settings"
    3. Find "Build Command" under Project Settings section
    4. Enable the "Override" toggle
    5. Enter: bunx convex deploy --cmd 'bun run build'
    6. Click "Save"

    Why this is needed:

    • The _generated directory is gitignored (as it should be)
    • bunx convex deploy deploys your Convex functions and generates these files
    • Then it runs bun run build to build your SvelteKit app
    • Without this, your build will fail with ENOENT: no such file or directory errors

    Note: Use the Project Settings section (not Production Overrides) so both production and preview deployments work correctly.

  4. Deploy:

    vercel --prod
    

Development Workflow

With CONVEX_DEPLOY_KEY set, your workflow is simple:

bunx convex dev         # Updates dev deployment locally
# Make changes
git push                # Automatically deploys BOTH frontend + Convex functions to production

What Each Environment Variable Does

  • PUBLIC_CONVEX_URL: Enables frontend to connect to your Convex backend (required)
  • CONVEX_DEPLOY_KEY: Enables automatic Convex function deployment with each Vercel build (required for full functionality)

Set Production Environment Variables

# Set production OAuth credentials
bunx convex env set AUTH_GOOGLE_ID your_google_client_id --prod
bunx convex env set AUTH_GOOGLE_SECRET your_google_client_secret --prod

# Set production email configuration
bunx convex env set RESEND_API_KEY your_resend_api_key --prod
bunx convex env set AUTH_EMAIL "[email protected]" --prod
bunx convex env set RESEND_WEBHOOK_SECRET your_webhook_secret --prod

Set Up Production Admin

After deploying to production, set up your first admin:

  1. Sign up on your production site with your admin email

  2. Run the seed command against production:

    bunx convex run admin/mutations:seedFirstAdmin '{"email":"[email protected]"}' --prod
    

This enables access to the Admin Panel at /admin.

Customization

Adding New Auth Providers

  1. Follow Convex Auth documentation to add providers
  2. Update src/lib/convex/auth.config.ts
  3. Add sign-in buttons to your UI

Styling

  • Modify src/app.css for global styles
  • Customize Tailwind configuration in tailwind.config.js

Database Schema

  • Edit src/lib/convex/schema.ts to add your data models
  • Create new functions in src/lib/convex/ for your business logic

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

MIT License - see the LICENSE file for details.

Top categories

Loading Svelte Themes