A production-ready, full-stack TypeScript starter template with Next.js 16 frontend/backend, AWS infrastructure managed by Pulumi, PostgreSQL with Drizzle ORM, and complete SaaS features including authentication, payments, monitoring, and email.
This starter template provides everything you need to build and deploy a modern SaaS application:
- π Full-stack TypeScript - End-to-end type safety from database to frontend
- β‘ Next.js 16 - App Router, React Server Components, and Server Actions
- π Authentication - Better Auth with email/password and OAuth (Google, GitHub, Apple)
- π³ Payments - Stripe integration with subscription management and webhooks
- ποΈ Database - PostgreSQL 16 with Drizzle ORM and migrations
- βοΈ Infrastructure - AWS resources managed with Pulumi (VPC, RDS, ECS, S3, CloudFront, SES)
- π Monitoring - Sentry error tracking, PostHog analytics, and CloudWatch logs
- π§ Email - React Email templates with AWS SES integration
- π Internationalization - Multi-language support with next-intl
- π Blog - MDX-based blog system with dynamic routing
- π Real-time - Server-Sent Events (SSE) support
- π SEO - Dynamic sitemap and robots.txt generation
- π§ͺ Testing - Vitest for unit/integration tests, Playwright for E2E tests
- π¨ UI Components - shadcn/ui with Tailwind CSS 4
- Next.js 16 (App Router)
- React 19
- TypeScript 5.7+
- Tailwind CSS 4
- shadcn/ui components
- Lucide React icons
- Next.js 16 API Routes
- tRPC 11 for type-safe APIs
- Better Auth for authentication
- Stripe for payments
- React Email for transactional emails
- PostgreSQL 16
- Drizzle ORM
- Drizzle Kit for migrations
- Pulumi (TypeScript) for IaC
- AWS (VPC, RDS, ECS, S3, CloudFront, SES, etc.)
Before you begin, ensure you have the following installed:
- Node.js 20.0.0 or higher
- pnpm 9.0.0 or higher (package manager)
- Docker & Docker Compose (for local development)
- Git (for version control)
- AWS account with appropriate permissions
- Pulumi CLI (Installation guide)
- Stripe account (test mode for development, production for deployment)
git clone <repo-url>
cd typescript-starter
pnpm installCreate a .env.local file in the apps/web directory with the following variables:
cd apps/web
touch .env.localRequired variables:
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
# Authentication
BETTER_AUTH_SECRET=your-secret-key-min-32-characters-long
BETTER_AUTH_URL=http://localhost:3000
# Application
NEXT_PUBLIC_APP_URL=http://localhost:3000
NODE_ENV=developmentOptional variables (for full functionality):
# OAuth Providers (optional)
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
APPLE_CLIENT_ID=your-apple-client-id
APPLE_CLIENT_SECRET=your-apple-client-secret
# Stripe (optional, for payments)
STRIPE_SECRET_KEY=sk_test_...
STRIPE_PUBLISHABLE_KEY=pk_test_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
# AWS SES (optional, for emails)
AWS_SES_REGION=us-east-1
AWS_SES_FROM_EMAIL=noreply@yourdomain.com
AWS_SES_FROM_NAME=Your App Name
# Redis (optional, for rate limiting)
UPSTASH_REDIS_REST_URL=https://...
UPSTASH_REDIS_REST_TOKEN=...
# Monitoring (optional)
SENTRY_DSN=https://...
NEXT_PUBLIC_SENTRY_DSN=https://...
NEXT_PUBLIC_POSTHOG_KEY=phc_...
NEXT_PUBLIC_POSTHOG_HOST=https://app.posthog.comNote: Generate
BETTER_AUTH_SECRETusing:openssl rand -base64 32
Start PostgreSQL and Redis using Docker Compose:
# From the project root
docker-compose up -dThis will start:
- PostgreSQL 16 on port
5432 - Redis 7 on port
6379
Verify services are running:
docker psYou should see both postgres and redis containers running.
Set up the database schema and seed initial data:
# Navigate to the web app
cd apps/web
# Generate database migrations from schema
pnpm db:generate
# Apply migrations to the database
pnpm db:migrate
# (Optional) Seed the database with sample data
pnpm db:seedTip: Use
pnpm db:studioto open Drizzle Studio, a visual database browser.
Start the development server:
# From the project root
pnpm devOr from the web app directory:
cd apps/web
pnpm devThe application will be available at http://localhost:3000.
Note: The dev server uses Turbopack by default for faster builds. If you encounter issues, you can run without Turbopack by modifying the
devscript inapps/web/package.json.
typescript-starter/
βββ apps/
β βββ web/ # Next.js application
β βββ app/ # App Router (Next.js 16)
β β βββ [locale]/ # Internationalized routes
β β β βββ (auth)/ # Authentication routes
β β β βββ (dashboard)/ # Protected dashboard routes
β β β βββ (marketing)/ # Public marketing pages
β β β βββ blog/ # Blog pages (MDX)
β β βββ api/ # API routes
β β β βββ auth/ # Auth endpoints
β β β βββ trpc/ # tRPC handler
β β β βββ sse/ # Server-Sent Events
β β β βββ webhooks/ # Webhook handlers
β β βββ sitemap.ts # Dynamic sitemap
β β βββ robots.ts # Dynamic robots.txt
β βββ components/ # React components
β β βββ ui/ # shadcn/ui components
β β βββ auth/ # Auth components
β β βββ dashboard/ # Dashboard components
β β βββ todos/ # Todo components
β βββ lib/ # Utilities and configurations
β β βββ i18n/ # Internationalization
β β βββ auth.ts # Auth configuration
β β βββ db.ts # Database client
β β βββ trpc.ts # tRPC setup
β β βββ stripe.ts # Stripe integration
β βββ server/ # Server-side code
β β βββ db/ # Database schema & queries
β β βββ trpc/ # tRPC routers & procedures
β β βββ services/ # Business logic services
β βββ emails/ # React Email templates
β βββ content/ # MDX blog posts
β βββ messages/ # i18n translation files
β βββ drizzle/ # Database migrations
β βββ tests/ # Test files
β β βββ e2e/ # Playwright E2E tests
β β βββ integration/ # Integration tests
β β βββ unit/ # Unit tests
β βββ scripts/ # Utility scripts
β
βββ packages/
β βββ infrastructure/ # Pulumi infrastructure as code
β βββ database.ts # RDS configuration
β βββ compute.ts # ECS configuration
β βββ network.ts # VPC configuration
β βββ ...
β
βββ docker-compose.yml # Local development services
βββ turbo.json # Turborepo configuration
βββ pnpm-workspace.yaml # pnpm workspace config
βββ README.md # This file
Run these commands from the project root or from apps/web:
pnpm dev # Start development server (with Turbopack)
pnpm build # Build for production
pnpm start # Start production server (after build)pnpm db:generate # Generate migrations from schema changes
pnpm db:migrate # Apply migrations to database
pnpm db:push # Push schema directly (dev only, no migrations)
pnpm db:studio # Open Drizzle Studio (visual DB browser)
pnpm db:seed # Seed database with sample datapnpm test # Run unit and integration tests (Vitest)
pnpm test:ui # Run tests with interactive UI
pnpm test:coverage # Run tests with coverage report
pnpm test:e2e # Run end-to-end tests (Playwright)
pnpm test:e2e:ui # Run E2E tests with Playwright UIpnpm lint # Lint code with Biome
pnpm lint:fix # Fix linting issues automatically
pnpm format # Format code with Biome
pnpm type-check # Type check with TypeScriptpnpm email:dev # Start email preview serverpnpm docker:build # Build Docker image
pnpm docker:run # Run Docker containerDrizzle Studio - Visual database browser:
pnpm db:studioOpens a web interface at http://localhost:4983 where you can:
- Browse tables and data
- Run queries
- Edit records
- View relationships
Preview React Email templates locally:
pnpm email:devThis starts a development server where you can preview all email templates.
This project uses end-to-end type safety:
- Database schema β TypeScript types (Drizzle)
- API routes β Type-safe clients (tRPC)
- Environment variables β Validated at runtime (Zod)
- Component props β TypeScript interfaces
Run pnpm type-check to verify type safety across the entire codebase.
This project uses Pulumi for infrastructure as code on AWS. For detailed deployment instructions, see the Deployment Guide.
-
Install Pulumi CLI: Installation guide
-
Configure AWS credentials:
aws configure
-
Initialize and deploy infrastructure:
cd packages/infrastructure pulumi stack init production pulumi config set aws:region us-east-1 pulumi preview # Review changes pulumi up # Deploy
- VPC - Isolated network environment
- RDS PostgreSQL - Managed database
- ECS Fargate - Containerized application
- Application Load Balancer - Traffic distribution
- S3 + CloudFront - Static asset hosting
- AWS SES - Email delivery
- Secrets Manager - Secure environment variables
See docs/DEPLOYMENT.md for complete deployment guide.
This project includes comprehensive testing setup. For detailed testing documentation, see the Testing Guide.
# Run all tests
pnpm test
# Run E2E tests
pnpm test:e2e
# Run with coverage
pnpm test:coverage- Unit Tests (
tests/unit/) - Test individual functions and utilities - Integration Tests (
tests/integration/) - Test API endpoints and tRPC procedures - E2E Tests (
tests/e2e/) - Test full user flows with Playwright
See docs/TESTING.md for complete testing guide.
- API Documentation - Complete tRPC API reference
- Deployment Guide - Step-by-step AWS deployment
- Testing Guide - Testing strategies and examples
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Run quality checks:
pnpm lint pnpm type-check pnpm test - Commit your changes:
git commit -m 'Add amazing feature' - Push to your branch:
git push origin feature/amazing-feature - Open a Pull Request
- Linting: Use Biome (configured in
biome.json) - TypeScript: Follow strict mode, avoid
anytypes - Naming: Use meaningful, descriptive names
- Formatting: Run
pnpm formatbefore committing - Testing: Add tests for new features
- Documentation: Update docs for significant changes
Problem: Cannot connect to PostgreSQL
Solutions:
- Verify Docker containers are running:
docker ps - Check
DATABASE_URLin.env.localmatches docker-compose.yml - Ensure database exists:
docker exec -it postgres psql -U user -d dbname - Restart containers:
docker-compose restart
Problem: Build fails with cryptic errors
Solutions:
- Clear Next.js cache:
rm -rf apps/web/.next - Clear Turbo cache:
pnpm clean - Reinstall dependencies:
rm -rf node_modules && pnpm install - Check Node.js version:
node --version(should be 20+)
Problem: TypeScript errors in IDE or build
Solutions:
- Run type check:
pnpm type-check - Restart TypeScript server in your IDE
- Ensure all dependencies are installed:
pnpm install - Check
tsconfig.jsonpaths are correct
Problem: Port 3000 is already in use
Solutions:
- Find process using port:
lsof -i :3000(macOS/Linux) ornetstat -ano | findstr :3000(Windows) - Kill the process or change port in
package.json:next dev -p 3001
Problem: Environment variables are undefined
Solutions:
- Ensure
.env.localis inapps/web/directory - Check variable names match
env.tsschema - Restart dev server after changing
.env.local - Verify no typos in variable names
Problem: Database migrations fail
Solutions:
- Check database connection:
pnpm db:studio - Verify migration files in
apps/web/drizzle/ - Reset database (dev only):
pnpm db:push(drops and recreates) - Check for conflicting migrations
- Check the project's GitHub Issues for similar problems
- Review the Deployment Guide for production issues
- Ensure all prerequisites are installed correctly
This project is licensed under the MIT License - see the LICENSE file for details.
- Next.js - The React framework
- Drizzle ORM - TypeScript ORM
- tRPC - End-to-end typesafe APIs
- Better Auth - Authentication library
- Pulumi - Infrastructure as code
- shadcn/ui - UI components
- Turborepo - Monorepo build system
Built with β€οΈ using modern web technologies