A modern full-stack monorepo built with Next.js, featuring both Supabase and Better Auth authentication options, Drizzle ORM, and a comprehensive UI component library.
- Node.js 20+
- pnpm (package manager)
- Docker & Docker Compose
- Git
-
Clone the repository
git clone <repository-url> cd monolith
-
Install dependencies
pnpm install
-
Environment Setup
# Copy root environment file cp .env.example .env # Copy web app environment file cp apps/web/.env.example apps/web/.env.local
Update the environment variables according to your setup (see Environment Variables section).
-
Start the development environment
# Start Supabase services (if using Supabase Auth) docker-compose up -d # Start the development server pnpm dev
This monorepo contains:
apps/web
- Next.js 15 application with App Routerpackages/database
- Drizzle ORM schema and clientpackages/ui
- Shared UI components library (shadcn/ui based)packages/transactional
- Email templates with React Emailpackages/typescript-config
- Shared TypeScript configurations
This project supports two authentication systems. Choose the one that best fits your needs:
β Use Supabase Auth if you want:
- Built-in authentication with minimal setup
- Social login providers out of the box
- Row Level Security (RLS)
- Real-time subscriptions
- Built-in email templates
- Dashboard for user management
Setup:
- Keep the Supabase Docker setup running
- Use Supabase client for authentication
- Remove Better Auth dependencies if not needed
β Use Better Auth if you want:
- Full control over authentication flow
- Custom user schemas and permissions
- Advanced features like 2FA, API keys, organizations
- Custom email templates
- More flexibility in authentication logic
Setup:
- The Better Auth configuration is already set up in
apps/web/src/lib/auth/
- Requires Redis for session storage (Upstash Redis configured)
- Uses your custom database schema
You should NOT use both systems simultaneously. Pick one based on your requirements:
- For rapid prototyping/MVP: Use Supabase Auth
- For production apps with complex auth requirements: Use Better Auth
To disable one system:
- To use only Supabase Auth: Remove Better Auth dependencies and auth configuration
- To use only Better Auth: Disable Supabase Auth services in docker-compose.yml
# Development
pnpm dev # Start all apps in development mode
pnpm build # Build all apps for production
pnpm lint # Lint all packages
pnpm lint:fix # Fix linting issues and format code
pnpm type-check # Run TypeScript type checking
# Database
pnpm db:generate # Generate Drizzle migrations
pnpm db:migrate # Run database migrations
pnpm db:push # Push schema changes to database
pnpm db:pull # Pull schema from database
pnpm db:studio # Open Drizzle Studio
# Testing
pnpm test # Run tests across all packages
# Utilities
pnpm clean # Clean build artifacts
The project uses multiple environment files:
- Root
.env
: Main application configuration (database, auth, services) - Web App
.env.local
: Next.js specific variables (public URLs, client-side config)
-
.env.example
β.env
(Root configuration)- Database connection settings
- Authentication secrets and API keys
- Email/SMTP configuration
- Supabase services configuration
- Security keys and secrets
-
apps/web/.env.example
βapps/web/.env.local
(Web app configuration)- Next.js public variables (
NEXT_PUBLIC_*
) - Client-side Supabase configuration
- Better Auth settings
- Redis configuration for sessions
- Next.js public variables (
- Database: PostgreSQL connection settings
- Authentication: JWT secrets, API keys (choose Supabase OR Better Auth)
- Email: SMTP configuration for transactional emails
- Storage: File upload and image processing
- External Services: Redis, analytics, monitoring
Security Note: Never commit actual .env
files to version control. Only the .env.example
files should be tracked.
The project uses:
- PostgreSQL as the primary database
- Drizzle ORM for type-safe database operations
- Migrations for schema management
Database schema is defined in packages/database/src/schema/
.
Transactional emails are handled via:
- React Email for template creation (
packages/transactional/
) - SMTP configuration for delivery
- Templates include: welcome, magic link, invite user, verify identity
The UI library (packages/ui/
) includes:
- shadcn/ui components
- Tailwind CSS for styling
- Lucide React for icons
- Next Themes for dark/light mode support
-
Build the application
pnpm build
-
Build Docker image
docker build -t monolith .
-
Deploy with Docker Compose
docker-compose -f docker-compose.yml up -d
- Development: Uses local Supabase instance
- Production: Update URLs and secrets in environment variables
monolith/
βββ apps/
β βββ web/ # Next.js application
βββ packages/
β βββ database/ # Drizzle ORM setup
β βββ ui/ # Shared UI components
β βββ transactional/ # Email templates
β βββ typescript-config/ # Shared TS configs
βββ supabase/ # Supabase Docker setup
βββ docker-compose.yml # Services orchestration
The project uses a multi-level environment configuration:
# Root level environment (main services)
/workspaces/monolith/.env.example β .env
# Web application environment (Next.js specific)
/workspaces/monolith/apps/web/.env.example β .env.local
Setup Order:
- Copy and configure root
.env
first (database, auth services) - Copy and configure web app
.env.local
second (client-side config) - Ensure both files have consistent URLs and keys
Environment Inheritance:
- Web app inherits some variables from root environment
- Web app
.env.local
takes precedence for Next.js specific variables - Database packages inherit
DATABASE_URL
from root environment
- New UI Components: Add to
packages/ui/src/components/
- Database Changes: Update schema in
packages/database/src/schema/
- API Routes: Add to
apps/web/src/app/api/
- Email Templates: Create in
packages/transactional/emails/
# Run all tests
pnpm test
# Run tests for specific package
pnpm --filter web test
pnpm --filter @workspace/database test
- Supabase Documentation
- Better Auth Documentation
- Next.js Documentation
- Drizzle ORM Documentation
- shadcn/ui Documentation
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature
- Commit your changes:
git commit -m 'Add amazing feature'
- Push to the branch:
git push origin feature/amazing-feature
- Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.