A production-ready SaaS starter template built for the Modern Stack Hackathon, featuring SvelteKit, Convex, Better Auth, Autumn Stripe billing, and more.
✅ Authentication System
✅ User Management
✅ UI Components
✅ Developer Experience
/docs + CLAUDE.md for AI-assisted developmentPlanned features and improvements:
git clone https://github.com/joachimchauvet/modernstack-saas
cd modernstack-saas
pnpm install
pnpm convex dev
When you run convex dev for the first time, it will:
CONVEX_DEPLOYMENT and PUBLIC_CONVEX_URL values in .env.localConvex functions run in Convex's cloud environment and can't read your local .env files. You must set environment variables separately for Convex and SvelteKit.
After convex dev completes, set these in Convex's environment:
# Required - Better Auth needs this to set cookies correctly
npx convex env set SITE_URL http://localhost:5173
# Required - Generate a secret for Better Auth
npx convex env set BETTER_AUTH_SECRET=$(openssl rand -base64 32)
# Required if you want email functionality (password reset, email change)
npx convex env set RESEND_API_KEY your_resend_api_key
npx convex env set RESET_EMAIL_FROM "Your App <[email protected]>"
# Optional - Customize reply to address
npx convex env set RESET_EMAIL_REPLY_TO [email protected]
# Optional - Enable Google OAuth (see docs/better_auth.md for setup)
npx convex env set GOOGLE_CLIENT_ID your_google_client_id
npx convex env set GOOGLE_CLIENT_SECRET your_google_client_secret
# Optional - Enable billing with Autumn/Stripe
npx convex env set AUTUMN_SECRET_KEY your_autumn_secret_key
Verify your Convex env vars are set:
npx convex env list
After setting Convex environment variables, restart your convex dev server (pnpm convex dev).
Update your .env.local file in the root directory:
# PUBLIC_CONVEX_URL is auto-generated by Convex
PUBLIC_CONVEX_URL=https://xxx.convex.cloud
# PUBLIC_CONVEX_SITE_URL: Convert the .convex.cloud URL to .convex.site
# Example: if PUBLIC_CONVEX_URL is https://xxx.convex.cloud,
# then PUBLIC_CONVEX_SITE_URL should be https://xxx.convex.site
PUBLIC_CONVEX_SITE_URL=https://xxx.convex.site
# This should match what you set in Convex (used by SvelteKit hooks)
SITE_URL=http://localhost:5173
pnpm dev
The app will be running at http://localhost:5173
Run both the SvelteKit dev server and Convex in parallel:
# Terminal 1 - Convex backend
pnpm convex dev
# Terminal 2 - SvelteKit frontend
pnpm dev
├── src/
│ ├── lib/
│ │ ├── components/ # UI components
│ │ ├── auth-client.ts # Better Auth client
│ │ └── ...
│ ├── routes/
│ │ ├── (app)/ # Protected routes
│ │ │ ├── dashboard/
│ │ │ └── settings/
│ │ └── auth/ # Authentication routes
│ └── convex/ # Convex backend
│ ├── auth.ts # Auth configuration
│ ├── storage.ts # File storage
│ └── ...
Create a production build:
pnpm build
Preview the production build:
pnpm preview
This starter uses adapter-cloudflare by default, but you can swap it for any SvelteKit adapter:
pnpm convex deploy
# Update SITE_URL to your production domain
npx convex env set SITE_URL https://yourdomain.com
# Set other Convex env vars if not already set
npx convex env set BETTER_AUTH_SECRET=$(openssl rand -base64 32)
npx convex env set RESEND_API_KEY your_resend_api_key
npx convex env set RESET_EMAIL_FROM "Your App <[email protected]>"
npx convex env set RESET_EMAIL_REPLY_TO [email protected]
npx convex env set GOOGLE_CLIENT_ID your_google_client_id
npx convex env set GOOGLE_CLIENT_SECRET your_google_client_secret
npx convex env set AUTUMN_SECRET_KEY your_autumn_secret_key
These variables use SvelteKit's $env/static/* imports, which means they're baked into the bundle at build time. Set them where your build runs, not in your hosting platform's runtime environment variables.
PUBLIC_CONVEX_URL - Your Convex deployment URLPUBLIC_CONVEX_SITE_URL - Your Convex site URLSITE_URL - Your production domain (e.g., https://yourdomain.com)If using GitHub Actions (like the included Cloudflare Pages workflow):
Set these as GitHub repository variables (Settings → Secrets and variables → Actions → Variables):
PUBLIC_CONVEX_URLPUBLIC_CONVEX_SITE_URLSITE_URLThe workflow will automatically use these during the build step.
If deploying directly from your machine or other CI/CD:
Set these as environment variables when running pnpm build:
wrangler secret put VARIABLE_NAME (for runtime secrets only)This project includes comprehensive documentation optimized for LLM consumption:
/docs - Framework-specific guides and best practicessvelte/ - Svelte 5 runes, reactivity, templating, and state managementbetter_auth.md - Authentication setup and patternsconvex.md - Backend queries, mutations, and real-time datatailwind_v4.md - Styling with Tailwind CSS v4autumn.md - Billing and subscription managementGitHub Actions workflows are included for:
.github/workflows/code-quality.yml) - Linting, formatting, type checking, and spell checking on every push/PR.github/workflows/cloudflare-pages.yml) - Automatic deployments with preview URLs for pull requests.github/workflows/deploy-workers.yml) - Alternative deployment target with more featuresThis starter template was created for the Convex Modern Stack Hackathon, showcasing the power of combining modern web technologies to build production-ready SaaS applications.
Stop plumbing, start vibing. Modern stack, zero setup headaches.
✓ Auth • ✓ Payments • ✓ Real-time DB • ✓ Your brilliant idea? Add here →
Fork & Ship on GitHub • MIT Licensed • Built for developers