A modern, full-stack monorepo built with the latest technologies and best practices.
This monorepo uses pnpm workspaces and Turbo for efficient development and builds. It includes:
apps/web- Next.js 15 frontend with App Router, TypeScript, and Tailwind CSSapps/ingest- Hono API for data ingestion, optimized for Cloudflare Workers
packages/db- Prisma schema and database clientpackages/trpc- Type-safe API layer with tRPC routerspackages/ui- Shared UI components built with shadcn/ui and Radixpackages/utils- Utility functions for rate limiting, IDs, validation, etc.packages/config- Shared configuration for TypeScript, Tailwind, and Biome
tooling/scripts- Database seeding, cron jobs, migrations, and backup scripts
- Framework: Next.js 15 (App Router)
- API: Hono (Cloudflare Workers ready)
- Database: PostgreSQL with Prisma ORM
- Type Safety: TypeScript + tRPC
- Styling: Tailwind CSS v4.1
- UI Components: shadcn/ui + Radix UI
- Linting/Formatting: Biome
- Package Manager: pnpm
- Build System: Turbo
- Payments: Stripe (configured)
- Node.js: v20.18.0 or higher
- pnpm: v9.0.0 or higher
- PostgreSQL: Running instance (local or remote)
- Docker: v20.10.0 or higher
- Docker Compose: v2.0.0 or higher
git clone <your-repo-url>
cd something-something
pnpm installCopy the example environment files and fill in your values:
# Web app
cp apps/web/env.example apps/web/.env.local
# Ingest app
cp apps/ingest/env.example apps/ingest/.envRequired Environment Variables:
DATABASE_URL- PostgreSQL connection stringNEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY- Stripe public keySTRIPE_SECRET_KEY- Stripe secret keySTRIPE_WEBHOOK_SECRET- Stripe webhook secretCRON_SECRET- Secret for cron job authentication
# Generate Prisma client
pnpm db:generate
# Push schema to database (for development)
pnpm db:push
# Or run migrations (for production)
pnpm db:migrate
# Seed the database with sample data
pnpm db:seed# Start all apps in development mode
pnpm dev
# Or start individual apps
pnpm web:dev # Next.js app on http://localhost:3000
pnpm ingest:dev # Hono API on http://localhost:8787The easiest way to get the entire stack running is with Docker Compose:
# 1. Clone the repository
git clone <your-repo-url>
cd something-something
# 2. Copy and configure environment variables
cp env.docker.example .env.docker
# Edit .env.docker with your actual values
# 3. Start all services (production-like)
docker-compose up --build
# Or start in detached mode
docker-compose up -d --buildThis will start:
- PostgreSQL database on
localhost:5432 - Next.js web app on
http://localhost:3000 - Hono ingest API on
http://localhost:8787 - Automatic database migrations and seeding
For development with hot reloading and code mounting:
# Start in development mode (uses docker-compose.override.yml automatically)
docker-compose up --build
# Or explicitly specify development profile
docker-compose -f docker-compose.yml -f docker-compose.override.yml up --buildDevelopment mode features:
- Hot reloading for both web and ingest apps
- Source code mounting for instant changes
- File watching with polling enabled for Docker
- Database exposed on
localhost:5432for external tools
# Build all images
docker-compose build
# Start services
docker-compose up -d
# View logs
docker-compose logs -f
docker-compose logs -f web # Web app logs only
docker-compose logs -f ingest # Ingest API logs only
# Stop services
docker-compose down
# Stop and remove volumes (β οΈ This will delete all data)
docker-compose down -v
# Restart a specific service
docker-compose restart web
# Execute commands in running containers
docker-compose exec web sh
docker-compose exec ingest sh
docker-compose exec db psql -U app -d app
# Run database commands
docker-compose exec web pnpm db:studio
docker-compose exec web pnpm db:seedFor production deployment, use the base docker-compose.yml without the override:
# Production build and start
docker-compose -f docker-compose.yml up -d --build
# Or disable the override file
mv docker-compose.override.yml docker-compose.override.yml.disabled
docker-compose up -d --buildBoth applications use optimized multi-stage builds:
Web App (apps/web/Dockerfile):
base: Node.js 20 Alpine with pnpm enableddeps: Dependency installation with pnpm fetchbuilder: Full build with Prisma generationrunner: Minimal production image with Next.js standalone output
Ingest API (apps/ingest/Dockerfile):
base: Node.js 20 Alpine with pnpm enableddeps: Dependency installation with pnpm fetchbuilder: TypeScript compilation with tsuprunner: Minimal production image with compiled JavaScript
All services include health checks:
- Database:
pg_isreadycheck - Web: HTTP check on
/api/health - Ingest: HTTP check on
/health
Services communicate via Docker's internal network:
- Web app β Ingest API:
http://ingest:8787 - Apps β Database:
postgres://app:app@db:5432/app
Build Issues:
# Clean build (no cache)
docker-compose build --no-cache
# Remove all containers and images
docker-compose down --rmi all
docker system prune -aPermission Issues:
# Fix file permissions (Linux/macOS)
sudo chown -R $USER:$USER .Database Issues:
# Reset database
docker-compose down -v
docker-compose up -d db
docker-compose up migrateDevelopment Hot Reload Issues:
- Ensure
CHOKIDAR_USEPOLLING=1is set in development - Check that source code is properly mounted
- Restart the specific service:
docker-compose restart web
# Development
pnpm dev # Start all apps in development
pnpm build # Build all packages and apps
pnpm lint # Lint all packages
pnpm format # Format all code with Biome
pnpm typecheck # Type check all packages
pnpm clean # Clean all build artifacts
# Database
pnpm db:generate # Generate Prisma client
pnpm db:push # Push schema to database
pnpm db:migrate # Run database migrations
pnpm db:reset # Reset database
pnpm db:seed # Seed database with sample data
pnpm db:studio # Open Prisma Studio
# Scripts
pnpm scripts:cron # Run cron jobs
pnpm scripts:migrate # Run data migrations
pnpm scripts:backup # Create database backup
# Individual Apps
pnpm web:dev # Start web app
pnpm web:build # Build web app
pnpm ingest:dev # Start ingest API
pnpm ingest:deploy # Deploy to Cloudflare Workers
# UI Components
pnpm ui:add # Add new shadcn/ui components
# Docker Commands
pnpm docker:up # Start all services with Docker
pnpm docker:up:prod # Start in production mode
pnpm docker:down # Stop all services
pnpm docker:down:clean # Stop and remove volumes
pnpm docker:logs # View all logs
pnpm docker:build # Rebuild all images# 1. Start the stack
pnpm docker:up
# 2. Make code changes (hot reload enabled)
# Edit files in apps/web/src or apps/ingest/src
# 3. View logs
pnpm docker:logs
# 4. Access services
# Web: http://localhost:3000
# API: http://localhost:8787
# DB: localhost:5432 (user: app, password: app, database: app)
# 5. Run database operations
docker-compose exec web pnpm db:studio
docker-compose exec web pnpm db:seed
# 6. Stop when done
pnpm docker:down# Add a new shadcn/ui component
pnpm ui:add button
# The component will be added to packages/ui/src/components/ui/
# and automatically exported from packages/ui/src/index.ts# 1. Modify packages/db/prisma/schema.prisma
# 2. Generate new client
pnpm db:generate
# 3. Push changes (development)
pnpm db:push
# OR create migration (production)
pnpm db:migrate- Create new directory in
packages/ - Add
package.jsonwith workspace dependencies - Update root
pnpm-workspace.yamlif needed - Add to
turbo.jsonpipeline if it has build steps
# Build and deploy
pnpm web:build
# Deploy to Vercel (configure in Vercel dashboard)# Deploy to Cloudflare Workers
pnpm ingest:deploy
# Configure environment variables in Cloudflare dashboard# Run migrations
pnpm db:migrate
# Seed production data (if needed)
pnpm db:seedsomething-something/
βββ apps/
β βββ web/ # Next.js frontend
β β βββ src/app/ # App Router pages
β β βββ src/components/ # App-specific components
β β βββ package.json
β βββ ingest/ # Hono API
β βββ src/
β βββ wrangler.toml # Cloudflare Workers config
β βββ package.json
βββ packages/
β βββ db/ # Database layer
β β βββ prisma/ # Prisma schema
β β βββ src/ # Database client
β βββ trpc/ # API layer
β β βββ src/routers/ # tRPC routers
β βββ ui/ # UI components
β β βββ src/components/ # shadcn/ui components
β βββ utils/ # Utility functions
β β βββ src/ # Rate limiting, IDs, validation
β βββ config/ # Shared configuration
β βββ tailwind.js # Tailwind config
β βββ src/ # TypeScript configs
βββ tooling/
β βββ scripts/ # Database scripts
β βββ src/ # Seed, cron, migration scripts
βββ package.json # Root package.json
βββ pnpm-workspace.yaml # Workspace configuration
βββ turbo.json # Turbo configuration
βββ tsconfig.base.json # Base TypeScript config
βββ biome.json # Biome configuration
biome.json- Code formatting and linting rulesturbo.json- Build pipeline configurationtsconfig.base.json- Base TypeScript configurationpnpm-workspace.yaml- Workspace package definitions
# Add your testing commands here
# Example:
# pnpm test # Run all tests
# pnpm test:watch # Run tests in watch modeSet up automated tasks using the cron script:
# Run maintenance tasks
pnpm scripts:cron
# This includes:
# - Processing unprocessed ingest events
# - Cleaning up old data
# - Generating daily statistics
# - Health checks# Create database backup
pnpm scripts:backup
# Backups are stored in ./backups/ directory
# Old backups are automatically cleaned up (keeps 5 most recent)- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Run linting and type checking:
pnpm lint && pnpm typecheck - 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.
pnpm install fails
- Ensure you're using Node.js v20.18.0 or higher
- Clear pnpm cache:
pnpm store prune
Database connection issues
- Check your
DATABASE_URLin environment files - Ensure PostgreSQL is running
- Verify database exists and is accessible
Build failures
- Run
pnpm cleanto clear build cache - Ensure all environment variables are set
- Check for TypeScript errors:
pnpm typecheck
Prisma issues
- Regenerate client:
pnpm db:generate - Reset database:
pnpm db:reset(β οΈ This will delete all data)
- Check the Issues page
- Review the documentation for each package
- Run
pnpm --helpfor pnpm commands - Run
turbo --helpfor Turbo commands
Built with β€οΈ using modern web technologies.