{"id":14964195,"url":"https://github.com/jdizm/turbo-nuxt-starter","last_synced_at":"2026-02-08T05:02:23.418Z","repository":{"id":247936503,"uuid":"824727644","full_name":"JDIZM/turbo-nuxt-starter","owner":"JDIZM","description":"A turborepo starter example with vue, nuxt, nitro, storybook, tailwind","archived":false,"fork":false,"pushed_at":"2025-09-28T11:07:38.000Z","size":2663,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-28T13:08:33.163Z","etag":null,"topics":["api","frontend","fullstack","monorepo","nitro","nuxt","storybook","tailwindcss","template","turbo","turborepo","vue"],"latest_commit_sha":null,"homepage":"","language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JDIZM.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-05T19:46:40.000Z","updated_at":"2025-09-28T11:07:41.000Z","dependencies_parsed_at":"2024-07-14T19:23:13.887Z","dependency_job_id":"0169b38f-e841-4a67-be7d-13e21e5dcfa9","html_url":"https://github.com/JDIZM/turbo-nuxt-starter","commit_stats":{"total_commits":57,"total_committers":2,"mean_commits":28.5,"dds":0.07017543859649122,"last_synced_commit":"9cc862f5c7a66ce0f73f3de29336f652daa0ae86"},"previous_names":["jdizm/turbo-nuxt-starter"],"tags_count":0,"template":true,"template_full_name":null,"purl":"pkg:github/JDIZM/turbo-nuxt-starter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JDIZM%2Fturbo-nuxt-starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JDIZM%2Fturbo-nuxt-starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JDIZM%2Fturbo-nuxt-starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JDIZM%2Fturbo-nuxt-starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JDIZM","download_url":"https://codeload.github.com/JDIZM/turbo-nuxt-starter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JDIZM%2Fturbo-nuxt-starter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":277746958,"owners_count":25870057,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-30T02:00:09.208Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","frontend","fullstack","monorepo","nitro","nuxt","storybook","tailwindcss","template","turbo","turborepo","vue"],"created_at":"2024-09-24T13:32:42.753Z","updated_at":"2026-02-08T05:02:23.409Z","avatar_url":"https://github.com/JDIZM.png","language":"Vue","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Turbo Nuxt Starter - Turborepo + Nuxt 4 + Vue 3 Monorepo\n\nA production-ready **Turborepo monorepo starter** template for building modern full-stack applications with **Nuxt 4**, **Vue 3**, Express/Nitro APIs, and PostgreSQL. Perfect for developers looking for a comprehensive **TypeScript monorepo** with component libraries, documentation, and production-grade infrastructure.\n\n## 🚀 Features\n\n### Full-Stack Monorepo Architecture\n\n- **Turborepo** - Intelligent build system with caching and parallel execution\n- **Multiple Apps** - Nuxt 4 frontend, Express API, Nitro server, Storybook, and Docus documentation\n- **Workspace Packages** - Shared UI components, type definitions, utilities, and database schemas\n- **pnpm 10** - Fast, disk-efficient package manager with built-in security features\n\n### Frontend Excellence\n\n- **Nuxt 4 + Vue 3** - Modern SSR framework with Composition API\n- **Tailwind CSS + DaisyUI** - Utility-first styling with pre-built components\n- **Pinia** - Type-safe state management\n- **Storybook** - Component-driven development with isolated testing\n- **TypeScript** - Full type safety across the entire stack\n\n### Backend Flexibility\n\n- **Express API** - Production-ready REST API with middleware, auth, and OpenAPI docs\n- **Nitro Server** - Modern server framework with edge deployment support\n- **PostgreSQL + Drizzle ORM** - Type-safe database with migrations and seed data\n- **Zod Validation** - Runtime schema validation with auto-generated TypeScript types\n\n### Production-Ready Infrastructure\n\n- **Docker Support** - Multi-stage builds with BuildKit caching and turbo prune\n- **GCP Cloud Run** - Terraform infrastructure with Workload Identity Federation\n- **CI/CD Pipelines** - GitHub Actions with automated deployments\n- **Corepack** - Automatic package manager version management\n- **Security** - Lifecycle script protection, minimum release age, rate limiting\n- **Structured Logging** - Pino logger for request tracking and debugging\n- **API Documentation** - Auto-generated OpenAPI/Swagger documentation\n- **Database Tools** - Drizzle Kit migrations with type-safe schema management\n- **Renovate** - Automated dependency updates with smart grouping\n\n### Developer Experience\n\n- **Docus Documentation** - Beautiful docs site powered by Nuxt Content\n- **Hot Module Replacement** - Fast development with instant updates\n- **Shared TypeScript Configs** - Consistent tsconfig across all packages\n- **ESLint + Prettier** - Code quality and formatting enforcement\n- **CI/CD Ready** - GitHub Actions workflows with prepare commands\n\n## Why This Starter?\n\n### 🎯 Comprehensive Yet Flexible\n\nUnlike minimal starters, this template provides **production-grade infrastructure** out of the box while remaining flexible enough to remove what you don't need. Choose between Express or Nitro for your API, use Storybook for component development, and deploy with Docker.\n\n### 🔒 Security-First Approach\n\nBuilt with **pnpm 10's latest security features** including lifecycle script protection and minimum release age settings. These features became critical after major npm supply chain attacks in 2025.\n\n### 📦 True Monorepo Architecture\n\nLeverages **Turborepo** for intelligent caching and parallel task execution. Shared packages (ui, helpers, api-types, db-schema, logger) demonstrate real-world monorepo patterns used in production applications.\n\n### 🚀 Modern Tech Stack\n\n- **Nuxt 4.1+** - Latest stable with Vue 3.5+ and Vite 6\n- **TypeScript 5.7+** - Strict mode with comprehensive type safety\n- **pnpm 10** - Fastest package manager with built-in security\n- **Node 22+ LTS** - Future-proof with long-term support\n\n### 📚 Documentation-Driven\n\nIncludes **Docus** (powered by Nuxt 4 + Nuxt Content) for beautiful, searchable documentation. Markdown-based content with Vue component support makes it easy to maintain comprehensive docs alongside your code.\n\n### 🎨 Component Library Ready\n\n**Storybook integration** with pre-built UI components (Button, Input, Card, Modal, Alert, Badge) demonstrates component-driven development patterns. Perfect for design systems and reusable components.\n\n### 🗄️ Database-Ready\n\nPostgreSQL + Drizzle ORM setup with migrations, seeds, and type-safe queries. Supabase Studio provides database management UI.\n\n## 🚀 Quick Start\n\n### Prerequisites\n\n- \\*\\*Node.js 22+ (LTS) - [Download](https://nodejs.org/)\n- **Corepack** - Package manager version manager (included with Node.js 16+)\n- **Docker** (for database) - [Get Docker](https://docs.docker.com/get-docker/)\n\nEnable Corepack if not already enabled:\n\n```bash\ncorepack enable\n```\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/your-org/turbo-nuxt-starter.git\ncd turbo-nuxt-starter\n\n# Install dependencies\npnpm install\n\n# Rebuild native modules (required for Docus/better-sqlite3)\npnpm rebuild better-sqlite3\n\n# Copy environment variables\ncp .env.example .env\n\n# Start PostgreSQL with Docker\ndocker-compose up -d postgres\n\n# Run database migrations\ncd packages/db-schema\npnpm migrate:push\ncd ../..\n\n# Start all apps\npnpm dev\n```\n\n## 🔐 Supabase Local Development\n\nThis starter includes **Supabase authentication** with local Docker development. No cloud account needed for development!\n\nThe `supabase/` directory at the root contains the Supabase CLI configuration shared by all apps.\n\n### Start Supabase\n\n```bash\n# Install Supabase CLI (if not already installed)\npnpm add -g supabase\n\n# Start local Supabase stack from root (PostgreSQL, Auth, Storage, etc.)\nsupabase start\n```\n\n### Configure Environment\n\nThis monorepo uses a **single root `.env` file** for all shared configuration.\n\n1. **Copy the example file:**\n\n   ```bash\n   cp .env.example .env\n   ```\n\n2. **Fill in Supabase credentials** from `supabase start` output:\n\n   ```bash\n   # Get credentials\n   supabase status -o env\n\n   # Copy these to root .env:\n   # - DATABASE_URL (replace \u003cYOUR_SUPABASE_PASSWORD\u003e)\n   # - SUPABASE_PUBLISHABLE_KEY\n   # - SUPABASE_SECRET_KEY\n   # - SUPABASE_JWT_SECRET\n   ```\n\n3. **(Optional) Add app-specific configuration:**\n   - **API**: `apps/api/.env` - OpenAPI config, Sentry DSN\n   - **Nuxt**: `apps/nuxt/.env` - Generate secret with `openssl rand -base64 32`\n   - **Nitro**: `apps/nitro/.env` - Port overrides\n\n#### Environment Variable Inheritance\n\n```\n┌─────────────────────────────────────┐\n│  Root .env (Single Source of Truth) │\n│  • DATABASE_URL                      │\n│  • SUPABASE_* (all keys)             │\n│  • CORS_ORIGIN                       │\n│  • All application ports             │\n│  • LOG_LEVEL                         │\n└─────────────┬───────────────────────┘\n              │ Inherited by all apps ↓\n    ┌─────────┴─────────┬──────────────┬──────────────┐\n    │                   │              │              │\n┌───▼──────┐    ┌──────▼───┐   ┌─────▼────┐   ┌────▼─────┐\n│ apps/api │    │apps/nuxt │   │apps/nitro│   │apps/docus│\n│ .env     │    │ .env     │   │ .env     │   │          │\n│ (OpenAPI)│    │ (Secrets)│   │  (Port)  │   │  (none)  │\n└──────────┘    └──────────┘   └──────────┘   └──────────┘\n```\n\n**Benefits:**\n\n- ✅ **DRY** - No duplicated env var definitions\n- ✅ **Single setup** - Copy one file, configure once\n- ✅ **Clear separation** - Obvious which vars are app-specific\n- ✅ **Docker-friendly** - `docker-compose` reads root `.env` automatically\n\n**About Supabase Keys:**\n\n- **API Keys** (`sb_publishable_*` or `anon`): For SDK initialization - functionally equivalent\n- **JWT System**: Newer asymmetric keys enable local token verification (faster, more secure)\n- Both servers use `supabase.auth.getClaims()` which automatically uses Web Crypto API with asymmetric keys\n- Learn more: [Supabase API Keys](https://supabase.com/docs/guides/api/api-keys) | [JWT Signing Keys](https://supabase.com/blog/jwt-signing-keys)\n\n### Run Database Migrations\n\n```bash\ncd packages/db-schema\npnpm migrate:push\n```\n\n### Seed Test Accounts (Optional)\n\n```bash\ncd apps/api\npnpm seed\n```\n\nThis creates 3 test accounts in Supabase Auth + database:\n\n- alice@example.com / password123\n- bob@example.com / password123\n- charlie@example.com / password123\n\n### Access Supabase Studio\n\nSupabase Studio (web UI) runs at **http://localhost:54323**\n\nManage users, view database, test Auth, and more!\n\n### Authentication Flow\n\n1. **Sign up a user** (creates Supabase Auth user + account record):\n\n```bash\ncurl -X POST http://localhost:3002/api/auth/signup \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"email\":\"alice@example.com\",\"password\":\"password123\",\"fullName\":\"Alice Johnson\"}'\n```\n\n2. **Sign in** (returns JWT access token):\n\n```bash\ncurl -X POST http://localhost:3002/api/auth/login \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"email\":\"alice@example.com\",\"password\":\"password123\"}'\n```\n\n3. **Access protected endpoints** (use JWT token):\n\n```bash\ncurl http://localhost:3002/api/me \\\n  -H \"Authorization: Bearer \u003cyour-jwt-token\u003e\"\n```\n\n### How Auth Works\n\n- **Supabase Auth** handles passwords, JWT tokens, sessions\n- **Both APIs** verify JWT tokens using `supabase.auth.getClaims()`\n  - With asymmetric keys: Local verification using Web Crypto API (fast, offline)\n  - With symmetric keys: Falls back to Auth server verification\n- **Account UUID** matches Supabase Auth user ID (synced on signup)\n- **Protected routes** require `Authorization: Bearer \u003ctoken\u003e` header\n\n### Useful Commands\n\n```bash\n# Check Supabase services status\nsupabase status\n\n# Stop all services\nsupabase stop\n\n# Reset database (WARNING: deletes all data)\nsupabase db reset\n\n# Generate migration from schema changes\nsupabase db diff -f migration_name\n```\n\n## What's inside?\n\nThis Turborepo includes the following packages/apps:\n\n### Apps and Packages\n\n- **`vite`** - [Vite](https://vitejs.dev/) + Vue 3 application (port 3000)\n- **`nuxt`** - [Nuxt 4](https://nuxt.com/) frontend application (port 3001)\n- **`api`** - [Express API](https://expressjs.com/) server with TypeScript (port 3002)\n- **`docus`** - [Docus](https://docus.dev/) documentation site (port 3003)\n- **`nitro`** - [Nitro](https://nitro.unjs.io/) server example (port 3004)\n- **`storybook`** - [Storybook](https://storybook.js.org/) for component development (port 6006)\n- **`ui`** - Shared Vue component library with Tailwind CSS\n- **`eslint-config-custom`** - ESLint configurations for different environments\n- **`tsconfig`** - Shared TypeScript configurations\n- **`tailwind-config`** - Shared Tailwind CSS configuration\n\nEach package/app is 100% [TypeScript](https://www.typescriptlang.org/).\n\n### Utilities\n\nThis Turborepo has some additional tools already setup for you:\n\n- [TypeScript](https://www.typescriptlang.org/) for static type checking\n- [ESLint](https://eslint.org/) for code linting\n- [Prettier](https://prettier.io) for code formatting\n\n## Development\n\n### Start All Services\n\nRun all applications simultaneously:\n\n```bash\npnpm dev\n```\n\nThis starts all applications on their configured ports:\n\n| Application   | Port | URL                   | Environment Variable |\n| ------------- | ---- | --------------------- | -------------------- |\n| Vite + Vue 3  | 3000 | http://localhost:3000 | -                    |\n| Nuxt Frontend | 3001 | http://localhost:3001 | NUXT_PORT            |\n| Express API   | 3002 | http://localhost:3002 | API_PORT             |\n| Docus Docs    | 3003 | http://localhost:3003 | DOCS_PORT            |\n| Nitro Server  | 3004 | http://localhost:3004 | NITRO_PORT           |\n| Storybook     | 6006 | http://localhost:6006 | -                    |\n\n**Infrastructure Services:**\n\n| Service         | Port  | URL                          | Environment Variable |\n| --------------- | ----- | ---------------------------- | -------------------- |\n| Supabase Studio | 54323 | http://localhost:54323       | -                    |\n| Supabase API    | 54321 | http://localhost:54321       | SUPABASE_URL         |\n| PostgreSQL      | 54322 | postgresql://localhost:54322 | POSTGRES_PORT        |\n\n### Individual Services\n\nStart specific services:\n\n```bash\n# Start only the API server\npnpm dev:api\n\n# Start only the Nuxt frontend\npnpm dev:web\n\n# Start Storybook\npnpm --filter storybook storybook\n```\n\n### Build\n\nBuild all applications and packages:\n\n```bash\npnpm build\n```\n\n### Dual Server Architecture\n\nThis monorepo provides **two production-ready API server options**:\n\n| Feature        | Express (Port 3002)              | Nitro (Port 3004)                 |\n| -------------- | -------------------------------- | --------------------------------- |\n| **Routing**    | Manual registration              | File-based (automatic)            |\n| **OpenAPI**    | `@asteasolutions/zod-to-openapi` | Built-in `defineRouteMeta`        |\n| **Deployment** | Traditional servers              | Edge-optimized, serverless        |\n| **Ecosystem**  | Mature, extensive middleware     | Modern, growing                   |\n| **Best For**   | Complex middleware chains        | Fast prototyping, edge deployment |\n\n**Shared Foundation:**\n\n- Both use identical workspace packages (api-types, db-schema, helpers, logger)\n- Same authentication flow (Supabase JWT verification)\n- Identical response formats and error handling\n- Complete database-backed CRUD operations with PostgreSQL + Drizzle ORM\n\n### API Endpoints\n\nBoth servers provide the same core functionality with slightly different route paths:\n\n#### Authentication Endpoints (Public)\n\n| Method | Express Route      | Nitro Route        | Description                    |\n| ------ | ------------------ | ------------------ | ------------------------------ |\n| POST   | `/api/auth/signup` | `/api/auth/signup` | Create new user account        |\n| POST   | `/api/auth/login`  | `/api/auth/login`  | Authenticate and get JWT token |\n| POST   | `/api/auth/logout` | `/api/auth/logout` | Logout (protected)             |\n\n#### User Endpoints (Protected - Requires JWT)\n\n| Method | Express Route    | Nitro Route | Description                    |\n| ------ | ---------------- | ----------- | ------------------------------ |\n| GET    | `/api/me`        | `/api/me`   | Get current user from database |\n| GET    | `/api/users`     | `/user`     | List all users                 |\n| GET    | `/api/users/:id` | `/user/:id` | Get user by ID                 |\n| PATCH  | `/api/users/:id` | `/user/:id` | Update user (self-update only) |\n| DELETE | `/api/users/:id` | `/user/:id` | Delete user (self-delete only) |\n\n#### Health \u0026 Info Endpoints\n\n| Method | Express Route | Nitro Route | Description         |\n| ------ | ------------- | ----------- | ------------------- |\n| GET    | `/health`     | `/health`   | Server health check |\n| GET    | `/api/`       | -           | API information     |\n\n### OpenAPI Documentation\n\nBoth servers provide interactive API documentation:\n\n- **Express Swagger UI**: http://localhost:3002/docs\n- **Nitro Swagger UI**: http://localhost:3004/\\_swagger\n- **Nitro Scalar UI**: http://localhost:3004/\\_scalar\n\nBoth support the **\"Authorize\" button** for testing protected endpoints with JWT tokens.\n\n### Example API Requests\n\n#### Signup\n\n```bash\ncurl -X POST http://localhost:3002/api/auth/signup \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"email\": \"user@example.com\",\n    \"password\": \"securePassword123\",\n    \"fullName\": \"John Doe\"\n  }'\n```\n\n#### Login\n\n```bash\ncurl -X POST http://localhost:3002/api/auth/login \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"email\": \"user@example.com\",\n    \"password\": \"securePassword123\"\n  }'\n```\n\nResponse includes JWT token:\n\n```json\n{\n  \"code\": 200,\n  \"data\": {\n    \"user\": { \"id\": \"...\", \"email\": \"...\" },\n    \"session\": { \"access_token\": \"eyJ...\", \"expires_in\": 3600 },\n    \"message\": \"Sign in successful\"\n  }\n}\n```\n\n#### Get Current User (Protected)\n\n```bash\ncurl http://localhost:3002/api/me \\\n  -H \"Authorization: Bearer YOUR_JWT_TOKEN\"\n```\n\n#### List Users (Protected)\n\n```bash\ncurl http://localhost:3002/api/users \\\n  -H \"Authorization: Bearer YOUR_JWT_TOKEN\"\n```\n\n#### Update User (Protected - Self-Update Only)\n\n```bash\ncurl -X PATCH http://localhost:3002/api/users/USER_UUID \\\n  -H \"Authorization: Bearer YOUR_JWT_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"fullName\": \"Jane Doe Updated\",\n    \"email\": \"updated@example.com\"\n  }'\n```\n\n**Authorization Pattern**: Users can only update or delete their own accounts. Attempting to modify another user's account returns `403 Forbidden`.\n\n### Database Integration\n\nBoth servers use **PostgreSQL with Drizzle ORM** for type-safe database operations:\n\n- **Connection**: Singleton pattern with `getDb()` from db-schema package\n- **Schema**: Shared `accounts` table with uuid, email, fullName, createdAt\n- **Migrations**: `pnpm db:migrate` applies schema changes\n- **Seeding**: `pnpm db:seed` populates test data\n- **Studio**: `pnpm db:studio` opens Drizzle Studio for visual database management\n\nDatabase connection details:\n\n```bash\n# PostgreSQL (via Supabase)\nHost: localhost\nPort: 54322\nDatabase: postgres\nUser: postgres\nPassword: postgres\n```\n\n## 🐳 Docker Deployment\n\nThis monorepo includes complete Docker configurations for all applications with optimized multi-stage builds.\n\n### Quick Start\n\n```bash\n# Build and start all services\ndocker compose build\ndocker compose up -d\n\n# Or combine into one command\ndocker compose up -d --build\n\n# View logs\ndocker compose logs -f\n\n# Stop all services\ndocker compose down\n```\n\n### Available Docker Services\n\nAll applications have individual Dockerfiles with multi-stage builds:\n\n| Service       | Port  | Dockerfile                  | Description         |\n| ------------- | ----- | --------------------------- | ------------------- |\n| **api**       | 3002  | `apps/api/Dockerfile`       | Express API server  |\n| **nitro**     | 3004  | `apps/nitro/Dockerfile`     | Nitro server        |\n| **nuxt**      | 3001  | `apps/nuxt/Dockerfile`      | Nuxt SSR frontend   |\n| **vite**      | 3000  | `apps/vite/Dockerfile`      | Vite static app     |\n| **docus**     | 3003  | `apps/docus/Dockerfile`     | Documentation site  |\n| **storybook** | 6006  | `apps/storybook/Dockerfile` | Component library   |\n| **postgres**  | 54322 | `postgres:16-alpine`        | PostgreSQL database |\n\n### Docker Compose Files\n\n**docker-compose.yml** - Production environment (default):\n\n- Optimized production builds\n- Health checks for all services\n- Automatic restarts\n- Minimal image sizes\n- Supabase integration (no PostgreSQL needed)\n\n**docker-compose.db.yml** - Optional local PostgreSQL:\n\n- Use this for local development without Supabase\n- Includes PostgreSQL 16 on port 54322\n- Persistent volume for data storage\n\n**Note**: For local development, use `pnpm dev` directly instead of Docker. Docker is primarily for production deployment testing.\n\n### Accessing Services\n\n**Standard localhost access:**\n\n- Vite: http://localhost:3000\n- Nuxt: http://localhost:3001\n- API: http://localhost:3002\n- Docus: http://localhost:3003\n- Nitro: http://localhost:3004\n- Storybook: http://localhost:6006\n\n**OrbStack users** (automatic HTTPS domains):\nIf you're using OrbStack instead of Docker Desktop, containers are automatically available at:\n\n- Vite: https://vite.turbo-nuxt-starter.orb.local\n- Nuxt: https://nuxt.turbo-nuxt-starter.orb.local\n- API: https://api.turbo-nuxt-starter.orb.local\n- Docus: https://docus.turbo-nuxt-starter.orb.local\n- Nitro: https://nitro.turbo-nuxt-starter.orb.local\n- Storybook: https://storybook.turbo-nuxt-starter.orb.local\n\nOrbStack provides automatic local DNS and SSL certificates for all running containers.\n\n### Building Individual Images\n\n```bash\n# Build specific app\ndocker build -f apps/api/Dockerfile -t turbo-api .\n\n# Build with BuildKit caching\nDOCKER_BUILDKIT=1 docker build -f apps/api/Dockerfile -t turbo-api .\n```\n\n### Common Docker Commands\n\n```bash\n# Build all services\ndocker compose build\n\n# Start services in background\ndocker compose up -d\n\n# Build and start (no cache)\ndocker compose build --no-cache \u0026\u0026 docker compose up -d\n\n# View logs\ndocker compose logs -f api\n\n# Stop all services\ndocker compose down\n\n# Remove volumes\ndocker compose down -v\n\n# Start with optional PostgreSQL database\ndocker compose -f docker-compose.yml -f docker-compose.db.yml up -d\n```\n\n### Environment Variables\n\nDocker services use environment variables from your `.env` file:\n\n```bash\n# Copy example environment file\ncp .env.example .env\n\n# Fill in required Supabase credentials\n# Get from: supabase status -o env\nSUPABASE_URL=http://localhost:54321\nSUPABASE_ANON_KEY=your-anon-key\nSUPABASE_AUTH_JWT_SECRET=your-jwt-secret\n```\n\n**Note**: `DATABASE_URL` is the connection string used by application code. Individual `POSTGRES_*` vars configure the PostgreSQL container in `docker-compose.db.yml`.\n\n### Docker Networking\n\n**Important**: Docker containers cannot access `localhost` - it refers to the container itself, not your host machine.\n\n- **Local dev (pnpm dev)**: Use `localhost` in URLs\n- **Docker accessing host services**: Replace `localhost` with `host.docker.internal`\n- **Production**: Use your hosted Supabase project URL (e.g., `https://your-project.supabase.co`)\n\nExample for Docker Compose accessing local Supabase:\n\n```bash\nSUPABASE_URL=http://host.docker.internal:54321\nDATABASE_URL=postgresql://postgres:postgres@host.docker.internal:54322/postgres\n```\n\n### Docker Image Optimization\n\nAll Dockerfiles use:\n\n- **Multi-stage builds** - Separate build and runtime stages\n- **BuildKit cache mounts** - Faster dependency installation\n- **pnpm** - Efficient monorepo package management\n- **Node 22 Alpine** - Minimal base images (~50MB)\n- **Non-root users** - Enhanced security\n\n### Health Checks\n\nProduction services include health checks:\n\n```yaml\n# API health check (defined in Dockerfile)\nhealthcheck:\n  test:\n    [\n      \"CMD\",\n      \"node\",\n      \"-e\",\n      \"require('http').get('http://localhost:3002/health', (r) =\u003e {process.exit(r.statusCode === 200 ? 0 : 1)})\"\n    ]\n  interval: 30s\n  timeout: 3s\n  retries: 3\n  start_period: 40s\n```\n\nCheck service health:\n\n```bash\ndocker compose ps\n```\n\n### Local Development vs Production\n\n**Local Development (pnpm dev)**\n\n- Uses `tsx` for on-the-fly TypeScript execution\n- Reads workspace packages as TypeScript source files\n- No build step required\n- Hot reload enabled\n\n**Production/Docker (pnpm start)**\n\n- Requires transpiled output (`dist/` directory)\n- Needs `node_modules` with built workspace packages\n- Express API depends on external workspace packages\n- Nuxt uses self-contained `.output` directory (includes bundled dependencies)\n\n**Why pnpm start fails locally:**\n\nThe Express API (`apps/api`) uses workspace packages (`logger`, `db-schema`, etc.) as TypeScript source. When tsup transpiles the API, it doesn't bundle these workspace packages. Docker containers include `node_modules` from the installer stage, but running `pnpm start` locally without a full workspace build will fail with TypeScript import errors.\n\n### Troubleshooting\n\n**Issue: Build fails with \"permission denied\"**\n\n```bash\n# Use BuildKit\nexport DOCKER_BUILDKIT=1\ndocker-compose build\n```\n\n**Issue: Port already in use**\n\n```bash\n# Change ports in .env file\nAPI_PORT=3012\nNUXT_PORT=3011\n```\n\n**Issue: Services can't connect to database**\n\n```bash\n# Use Docker service name for DATABASE_URL\nDATABASE_URL=postgresql://postgres:postgres@postgres:5432/postgres\n```\n\n## Project Structure\n\n```\nturbo-nuxt-starter/\n├── apps/\n│   ├── api/                 # Express.js API server\n│   │   ├── src/\n│   │   │   ├── routes/      # API routes\n│   │   │   └── server.ts    # Main server file\n│   │   ├── package.json\n│   │   └── tsconfig.json\n│   ├── nuxt/               # Nuxt 3 frontend\n│   ├── nitro/              # Nitro server example\n│   ├── storybook/          # Component development\n│   └── vite/               # Vite + Vue 3 app\n├── packages/\n│   ├── ui/                 # Shared Vue components\n│   ├── eslint-config-custom/ # ESLint configurations\n│   ├── tsconfig/           # TypeScript configurations\n│   └── tailwind-config/    # Tailwind CSS config\n├── package.json            # Root workspace config\n└── turbo.json             # Turborepo configuration\n```\n\n## Environment Configuration\n\n### API Environment Variables\n\nCopy `.env.example` to `.env` in the API directory:\n\n```bash\ncp apps/api/.env.example apps/api/.env\n```\n\nConfigure as needed:\n\n- `PORT` - API server port (default: 3002)\n- `NODE_ENV` - Environment (development/production)\n- `CORS_ORIGIN` - CORS allowed origin\n\n## Adding New Features\n\n### New API Routes\n\n1. Create route file in `apps/api/src/routes/`\n2. Export router and import in `apps/api/src/routes/index.ts`\n\n### New UI Components\n\n1. Add component to `packages/ui/`\n2. Export from `packages/ui/index.ts`\n3. Use in any app: `import { MyComponent } from 'ui'`\n\n### Shared Types\n\nAdd TypeScript types to `packages/ui/types/` for cross-package usage.\n\n### Remote Caching\n\nTurborepo can use a technique known as [Remote Caching](https://turbo.build/repo/docs/core-concepts/remote-caching) to share cache artifacts across machines, enabling you to share build caches with your team and CI/CD pipelines.\n\nBy default, Turborepo will cache locally. To enable Remote Caching you will need an account with Vercel. If you don't have an account you can [create one](https://vercel.com/signup), then enter the following commands:\n\n```\ncd my-turborepo\nnpx turbo login\n```\n\nThis will authenticate the Turborepo CLI with your [Vercel account](https://vercel.com/docs/concepts/personal-accounts/overview).\n\nNext, you can link your Turborepo to your Remote Cache by running the following command from the root of your Turborepo:\n\n```\nnpx turbo link\n```\n\n## CI/CD Setup\n\n### TypeScript Configuration Generation\n\nNuxt and Nitro apps generate their TypeScript configurations at prepare time:\n\n- `apps/nuxt/.nuxt/tsconfig.json` - Generated by `nuxt prepare`\n- `apps/nitro/.nitro/tsconfig.json` - Generated by `nitro prepare`\n- `apps/docus/.nuxt/tsconfig.json` - Generated by `nuxt prepare --extends docus`\n\n**Local Development:**\n\n- These are generated automatically via `postinstall` scripts when you run `pnpm install`\n- No manual action required\n\n**CI/CD Pipelines:**\n\n- If you skip postinstall scripts (common practice with `--ignore-scripts`), you must run `turbo prepare` before typechecking\n- This ensures all `.nuxt` and `.nitro` directories are generated with proper TypeScript configurations\n\n### Example GitHub Actions Workflow\n\n```yaml\nname: CI\n\non: [push, pull_request]\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - uses: pnpm/action-setup@v2\n        with:\n          version: 10.17.1\n\n      - uses: actions/setup-node@v4\n        with:\n          node-version: 22\n          cache: \"pnpm\"\n\n      # Install dependencies (skip postinstall for speed)\n      - run: pnpm install --frozen-lockfile --ignore-scripts\n\n      # Rebuild native modules\n      - run: pnpm rebuild better-sqlite3\n\n      # Generate TypeScript configs for Nuxt/Nitro\n      - run: turbo prepare\n\n      # Run quality checks\n      - run: turbo lint:check\n      - run: turbo typecheck\n      - run: turbo test:unit\n      - run: turbo build\n```\n\n### Manual Prepare Command\n\nIf you need to manually regenerate TypeScript configurations:\n\n```bash\n# Regenerate all configs\nturbo prepare\n\n# Or for a specific app\npnpm --filter nuxt prepare\npnpm --filter nitro prepare\npnpm --filter docus prepare\n```\n\n## Useful Links\n\nLearn more about the power of Turborepo:\n\n- [Tasks](https://turbo.build/repo/docs/core-concepts/monorepos/running-tasks)\n- [Caching](https://turbo.build/repo/docs/core-concepts/caching)\n- [Remote Caching](https://turbo.build/repo/docs/core-concepts/remote-caching)\n- [Filtering](https://turbo.build/repo/docs/core-concepts/monorepos/filtering)\n- [Configuration Options](https://turbo.build/repo/docs/reference/configuration)\n- [CLI Usage](https://turbo.build/repo/docs/reference/command-line-reference)\n\n## Troubleshooting\n\n### TypeScript Configuration Not Found\n\nIf `pnpm typecheck` fails with errors about missing TypeScript configurations or cannot find auto-imported functions (`useHead`, `defineNuxtConfig`, etc.):\n\n**Cause:** The `.nuxt` and `.nitro` directories haven't been generated yet.\n\n**Solution:**\n\n```bash\n# Regenerate TypeScript configurations\nturbo prepare\n\n# Then run typecheck again\npnpm typecheck\n```\n\nThis is especially common in CI/CD environments when using `pnpm install --ignore-scripts`. See the [CI/CD Setup](#cicd-setup) section for more details.\n\n### better-sqlite3 Bindings Error\n\nIf you encounter an error like `Could not locate the bindings file` when running the Docus app, it means the native module `better-sqlite3` needs to be rebuilt for your system.\n\n**Error example:**\n\n```\nError: Could not locate the bindings file. Tried:\n→ /path/to/node_modules/better-sqlite3/build/better_sqlite3.node\n```\n\n**Solution:**\n\n```bash\n# Rebuild the native module\npnpm rebuild better-sqlite3\n```\n\nThis is required because `better-sqlite3` is a native Node.js addon that must be compiled for your specific:\n\n- Node.js version (e.g., Node 22.17.0)\n- Operating system (macOS, Linux, Windows)\n- CPU architecture (arm64, x64)\n\nThe rebuild command will compile the module correctly for your environment.\n\n## Deployment\n\nThis monorepo includes complete infrastructure for deploying to **GCP Cloud Run**.\n\n### Quick Deployment\n\n```bash\n# 1. Configure Terraform\ncd infra/terraform\ncp terraform.tfvars.example terraform.tfvars\n# Edit terraform.tfvars with your GCP project ID\n\n# 2. Apply infrastructure\nterraform init\nterraform apply\n\n# 3. Push images\ngcloud auth configure-docker europe-west1-docker.pkg.dev\ndocker build -f apps/api/Dockerfile -t europe-west1-docker.pkg.dev/PROJECT/turbo-repo/api:latest .\ndocker push europe-west1-docker.pkg.dev/PROJECT/turbo-repo/api:latest\n```\n\n### What's Included\n\n| Component                      | Description                                           |\n| ------------------------------ | ----------------------------------------------------- |\n| `infra/terraform/`             | GCP Cloud Run, Artifact Registry, Secret Manager, IAM |\n| `.github/workflows/ci.yml`     | Lint, typecheck, test, build on PRs                   |\n| `.github/workflows/deploy.yml` | Build Docker images, deploy to Cloud Run              |\n| `renovate.json`                | Automated dependency updates                          |\n| `docker-compose.dev.yml`       | Local development with hot reload                     |\n\n### CI/CD Workflows\n\n- **ci.yml** - Runs on all PRs: lint, typecheck, test, build\n- **deploy.yml** - Runs on main: build images, deploy to Cloud Run\n\n### GitHub Secrets Required\n\n| Secret                           | Description             |\n| -------------------------------- | ----------------------- |\n| `GCP_PROJECT_ID`                 | Your GCP project ID     |\n| `GCP_REGION`                     | e.g., `europe-west1`    |\n| `GCP_WORKLOAD_IDENTITY_PROVIDER` | From `terraform output` |\n| `GCP_SERVICE_ACCOUNT`            | From `terraform output` |\n\n### Documentation\n\nFull deployment documentation is available at:\n\n- **Docus Site**: Run `pnpm --filter docus dev` and visit http://localhost:3003/deployment\n- **Infrastructure README**: `infra/README.md`\n\n## Security Features (pnpm 10)\n\nThis starter uses **pnpm 10** with enhanced security features to protect against supply chain attacks.\n\n### Lifecycle Script Protection\n\n**By default, lifecycle scripts from dependencies are disabled.** This prevents malicious packages from executing arbitrary code during installation.\n\nOnly explicitly allowed packages can run lifecycle scripts, configured in `pnpm-workspace.yaml`:\n\n```yaml\nonlyBuiltDependencies:\n  - better-sqlite3 # Native module requiring compilation\n  - esbuild # Build tool needing platform binaries\n```\n\nIf you need to allow additional packages to run lifecycle scripts, add them to this list.\n\n### Minimum Release Age\n\n**New package versions are delayed by 24 hours before installation** to give the community time to identify malicious releases.\n\n```yaml\nminimumReleaseAge: 1440 # 24 hours in minutes\n```\n\nThis setting is configured in `pnpm-workspace.yaml` and helps protect against:\n\n- Compromised maintainer accounts\n- Malicious package updates\n- Supply chain injection attacks\n\n**Note:** This only affects newly published versions. Existing versions install immediately.\n\n### Package Manager Version Management\n\nCorepack automatically manages the pnpm version based on the `packageManager` field in `package.json`:\n\n```json\n{\n  \"packageManager\": \"pnpm@10.17.1\"\n}\n```\n\nThis ensures everyone on your team uses the same pnpm version, eliminating \"works on my machine\" issues.\n\n### Learn More\n\n- [pnpm Supply Chain Security](https://pnpm.io/supply-chain-security)\n- [pnpm 10 Release Notes](https://pnpm.io/blog/releases/10.16)\n- [Corepack Documentation](https://nodejs.org/api/corepack.html)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjdizm%2Fturbo-nuxt-starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjdizm%2Fturbo-nuxt-starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjdizm%2Fturbo-nuxt-starter/lists"}