A comprehensive SaaS template built for real-time, workflow-driven applications. Features local-first architecture with offline support, serverless workflow orchestration, and seamless real-time collaboration. Designed to launch sophisticated SaaS products in days rather than weeks.
- Authentication: Google OAuth integration
- Database: Supabase with Drizzle ORM
- Type Safety: End-to-end with tRPC
- Monitoring: Sentry for errors, Axiom for logging
- Multi-tenancy: Basic organization system with email invitations
- Email: Resend integration with templates
- Real-time Sync: Electric SQL for local-first architecture
- Workflow Engine: Inngest for serverless workflow orchestration
- Payments: Stripe integration with webhook handling
- Offline Support: 100% functionality available offline
- Collaboration: Real-time multi-user collaboration
Week 1 - Real-time Infrastructure
- Electric SQL setup for local-first architecture
- Offline support with automatic sync
- Real-time hooks and sync status UI
Week 2 - Complete Authentication
- GitHub OAuth, email/password, magic links
- Password reset and email verification
- Session management improvements
Week 3 - Workflow Engine
- Inngest setup for serverless workflows
- Progress tracking and state persistence
- Error handling and recovery
Week 4 - Payment System
- Stripe integration with webhook handling
- Subscription management and customer portal
- Usage tracking and billing
Week 5 - Component Library
- Complete design system with dark mode
- Form, feedback, and data display components
- Layout components and responsive design
Week 6 - Dashboard & Templates
- Dashboard layouts and landing pages
- Workflow status UI with real-time updates
- Mobile-responsive templates
Week 7 - File & Background Systems
- File upload with progress tracking
- Background job processing
- Progress indicators and error handling
Week 8 - RBAC & Security
- Role-based access control
- Permissions system and audit logging
- Security headers and rate limiting
Week 9 - Advanced Workflows
- Workflow templates and parallel execution
- Conditional branching and scheduling
- Human approvals and analytics
Week 10 - Real-time Collaboration
- Multi-user real-time collaboration
- Conflict resolution and team management
- Enhanced offline support
Week 11 - Performance & Scale
- Performance optimization and caching
- Monitoring dashboards
- API rate limiting
Week 12 - Operations & Documentation
- Feature flags and health monitoring
- Comprehensive documentation
- Testing suite and deployment guides
- Local-first architecture with automatic sync
- Serverless workflow orchestration with zero infrastructure
- Full offline functionality (100% feature availability)
- Real-time collaboration built-in
- Type-safe from database to UI
- Enterprise-ready RBAC, audit trails, comprehensive monitoring
- Time to MVP: < 7 days (after template completion)
- Workflow reliability: 99.9% completion rate
- Real-time sync: < 100ms local latency
- Performance: 90+ Lighthouse score
- Offline support: 100% functionality available
- Node.js 18+ and pnpm
- Docker (for local Supabase development)
- A Supabase project (for production)
- Resend account (for emails)
This project requires environment variables in two locations:
-
For the Next.js application (
apps/web/):cp apps/web/.env.example apps/web/.env.local
-
For Supabase local development (
packages/crud/):cp packages/crud/.env.example packages/crud/.env
Then follow the guides below to obtain each set of credentials.
- Important: Before starting Supabase, you need Google OAuth credentials in
packages/crud/.env:# Add these to packages/crud/.env (can be empty for local development) SUPABASE_AUTH_GOOGLE_CLIENT_ID= SUPABASE_AUTH_GOOGLE_SECRET= - Start Supabase locally:
pnpm supabase:start
- After startup, you'll see output with your local credentials - add these to
apps/web/.env.local:API URL→NEXT_PUBLIC_SUPABASE_URLanon key→NEXT_PUBLIC_SUPABASE_ANON_KEYservice_role key→SUPABASE_SERVICE_ROLE_KEYDATABASE_URLwill bepostgresql://postgres:postgres@localhost:54322/postgres
- Create a project at supabase.com
- Go to Settings → API:
URL→NEXT_PUBLIC_SUPABASE_URLanon public→NEXT_PUBLIC_SUPABASE_ANON_KEYservice_role→SUPABASE_SERVICE_ROLE_KEY
- Go to Settings → Database:
- Connection string →
DATABASE_URL
- Connection string →
- Go to Google Cloud Console
- Create a new project or select existing
- Enable Google+ API
- Go to Credentials → Create Credentials → OAuth client ID
- Application type: Web application
- Add authorized redirect URIs:
- Local Supabase:
http://localhost:54321/auth/v1/callback - Production Supabase:
https://your-project-ref.supabase.co/auth/v1/callback
- Local Supabase:
- Copy the Client ID and Client Secret:
- Client ID →
SUPABASE_AUTH_GOOGLE_CLIENT_ID(add topackages/crud/.env) - Client Secret →
SUPABASE_AUTH_GOOGLE_SECRET(add topackages/crud/.env)
- Client ID →
- Sign up at resend.com
- Verify your domain (for production)
- Go to API Keys
- Create a new API key
- Copy the key to
RESEND_API_KEY
Comprehensive payment system planned for Week 4:
- Stripe integration with webhook handling
- Subscription management and customer portal
- Multiple pricing tiers and free trials
- Usage-based billing support
- Sign up at axiom.co
- Create a dataset
- Go to Settings → API tokens
- Create a new ingest token
- Copy token →
NEXT_PUBLIC_AXIOM_TOKEN
- Sign up at sentry.io
- Create a new project (Next.js)
- Go to Settings → Projects → [Your Project] → Client Keys
- Copy DSN →
SENTRY_DSN
- Go to api.slack.com/apps
- Create New App → From scratch
- Add OAuth & Permissions:
- Redirect URLs:
https://yourdomain.com/api/integrations/slack/callback - Scopes:
chat:write,incoming-webhook
- Redirect URLs:
- From Basic Information:
- Client ID →
SLACK_CLIENT_ID - Client Secret →
SLACK_CLIENT_SECRET
- Client ID →
# Install dependencies
pnpm install
# Start local Supabase
pnpm supabase:start
# Run database migrations
pnpm supabase:db:push
# Start development server
pnpm devZero local cache can be run alongside the app for the Zero-powered Todos feature.
-
Start the Zero cache (in a separate terminal):
pnpm run dev:zero
This will print the local cache URL (default often
http://localhost:4243). -
Configure the web app to point to Zero:
- Add to
apps/web/.env.local:NEXT_PUBLIC_ZERO_URL=http://localhost:4243 # Optional feature flag to toggle Zero in the Todos page while migrating # NEXT_PUBLIC_USE_ZERO=true
- Add to
Auth token strategy (Zero path): the app now passes the Supabase session access_token to Zero via a client wrapper. When NEXT_PUBLIC_USE_ZERO is enabled and NEXT_PUBLIC_ZERO_URL is set, the organization layout wraps content with a Zero provider using the current Supabase session's access_token for auth. In local development, Supabase uses a symmetric JWT secret, so the access_token is a symmetrically signed JWT. Ensure your Zero cache/server validates this token appropriately in non-local environments.
References:
- ztunes (Zero example app): github.com/rocicorp/ztunes
- Push your code to GitHub
- Import project in Vercel
- Add all environment variables from your
.envfile - Deploy
Note: VERCEL_URL is automatically set by Vercel, so you don't need NEXTAUTH_URL in production on Vercel.
Ensure all required environment variables are set in your platform's environment configuration.
-
"Invalid environment variables" error
- Check that all required variables are set in
.env - Ensure no trailing spaces in values
- Restart the dev server after changing
.env
- Check that all required variables are set in
-
Supabase connection errors
- Ensure local Supabase is running:
pnpm supabase:start - Check that the URLs and keys match the output
- Ensure local Supabase is running:
-
OAuth redirect errors
- Verify redirect URIs match exactly in Google Cloud Console
- Include both http://localhost:3000 and your production URL
-
Email sending failures
- Verify your domain in Resend for production
- Check API key permissions
- Never commit
.envfiles to version control - Rotate
NEXTAUTH_SECRETregularly in production - Use different API keys for development and production
- Keep
SUPABASE_SERVICE_ROLE_KEYsecure - it bypasses Row Level Security