# Convex Turbo Monorepo A production-ready Turborepo starter with Next.js, Expo, and self-hosted Convex backend. Built with TypeScript, Tailwind CSS, and modern tooling. --- ## What's Inside? ### Apps & Packages - **`apps/next`** - Next.js 16 web application with App Router - **`apps/expo`** - Expo 54 mobile application _(in progress)_ - **`@gib/backend`** - Self-hosted Convex backend with authentication - **`@gib/ui`** - Shared shadcn/ui component library - **`@gib/eslint-config`** - ESLint configuration - **`@gib/prettier-config`** - Prettier configuration with import sorting - **`@gib/tailwind-config`** - Tailwind CSS v4 configuration - **`@gib/tsconfig`** - Shared TypeScript configurations ### Tech Stack - **Framework:** Next.js 16 (App Router) + Expo 54 - **Backend:** Convex (self-hosted) - **Auth:** @convex-dev/auth with Authentik OAuth & Password providers - **Styling:** Tailwind CSS v4 + shadcn/ui - **Language:** TypeScript (strict mode) - **Package Manager:** Bun - **Monorepo:** Turborepo - **Deployment:** Docker (standalone) --- ## Getting Started ### Prerequisites - [Bun](https://bun.sh) (v1.2.19+) - [Docker](https://www.docker.com/) & Docker Compose (for self-hosted Convex) - Node.js 22.20.0+ (for compatibility) ### Development Setup #### 1. Clone & Install ```bash git clone cd convex-monorepo bun install ``` #### 2. Configure Environment Variables Create a `.env` file in the project root with the following variables: ```bash # Convex Backend (Self-Hosted) CONVEX_SELF_HOSTED_URL=https://api.convex.example.com CONVEX_SELF_HOSTED_ADMIN_KEY= CONVEX_SITE_URL=https://convex.example.com # Next.js Public NEXT_PUBLIC_CONVEX_URL=https://api.convex.example.com NEXT_PUBLIC_SITE_URL=https://example.com NEXT_PUBLIC_PLAUSIBLE_URL=https://plausible.example.com NEXT_PUBLIC_SENTRY_DSN= NEXT_PUBLIC_SENTRY_URL= NEXT_PUBLIC_SENTRY_ORG= NEXT_PUBLIC_SENTRY_PROJECT_NAME= # Server-side SENTRY_AUTH_TOKEN= # Auth (will be synced to Convex) AUTH_AUTHENTIK_ID= AUTH_AUTHENTIK_SECRET= AUTH_AUTHENTIK_ISSUER= USESEND_API_KEY= ``` **For local development:** Use `http://localhost:3210` for Convex URLs. #### 3. Configure Docker Environment Check and update environment variables in `docker/.env` for your deployment: ```bash cd docker/ cp .env.example .env # Edit .env with your configuration ``` #### 4. Start Self-Hosted Convex Spin up the Convex backend and dashboard: ```bash cd docker/ docker compose up -d convex-backend convex-dashboard ``` **Services:** - **Backend:** http://localhost:3210 - **Dashboard:** http://localhost:6791 #### 5. Generate Auth Keys & Sync Environment Variables Generate JWT keys for Convex Auth: ```bash cd packages/backend bun run scripts/generateKeys.mjs ``` Sync environment variables to Convex deployment (via CLI or Dashboard): ```bash cd packages/backend bun with-env npx convex env set AUTH_AUTHENTIK_ID "your-value" bun with-env npx convex env set AUTH_AUTHENTIK_SECRET "your-value" bun with-env npx convex env set AUTH_AUTHENTIK_ISSUER "your-issuer-url" bun with-env npx convex env set USESEND_API_KEY "your-api-key" bun with-env npx convex env set CONVEX_SITE_URL "http://localhost:3000" ``` **Important:** For local development, set `CONVEX_SITE_URL` to `http://localhost:3000`. #### 6. Start Development Server ```bash # From project root bun dev:next # Next.js app + Convex backend # or bun dev # All apps (Next.js + Expo + Backend) ``` **App URLs:** - **Next.js:** http://localhost:3000 - **Convex Dashboard:** http://localhost:6791 --- ## Development Commands ```bash # Development bun dev # Run all apps bun dev:next # Next.js + Convex backend bun dev:expo # Expo + Convex backend bun dev:backend # Convex backend only # Quality Checks bun typecheck # Type checking (recommended for testing) bun lint # Lint all packages bun lint:fix # Lint and auto-fix bun format # Check formatting bun format:fix # Fix formatting # Build bun build # Build all packages (production) # Utilities bun ui-add # Add shadcn/ui components bun clean # Clean node_modules bun clean:ws # Clean workspace caches ``` ### Single Package Commands Use Turborepo filters to target specific packages: ```bash bun turbo run dev -F @gib/next # Run Next.js only bun turbo run typecheck -F @gib/backend # Typecheck backend bun turbo run lint -F @gib/ui # Lint UI package ``` --- ## Project Structure ``` convex-monorepo/ ├── apps/ │ ├── next/ # Next.js web app │ │ ├── src/ │ │ │ ├── app/ # App Router pages │ │ │ ├── components/ # React components │ │ │ └── lib/ # Utilities │ │ └── package.json │ └── expo/ # Expo mobile app (WIP) │ ├── packages/ │ ├── backend/ # Convex backend │ │ ├── convex/ # Convex functions (synced to cloud) │ │ ├── scripts/ # Utilities (generateKeys.mjs) │ │ └── types/ # Shared types │ └── ui/ # shadcn/ui components │ └── src/ # Component source files │ ├── tools/ # Shared configurations │ ├── eslint/ │ ├── prettier/ │ ├── tailwind/ │ └── typescript/ │ ├── docker/ # Self-hosted deployment │ ├── compose.yml │ ├── Dockerfile │ └── .env.example │ ├── turbo.json # Turborepo configuration └── package.json # Root workspace & catalogs ``` --- ## Features ### Authentication - **OAuth:** Authentik SSO integration - **Password:** Custom password auth with email verification - **OTP:** Email verification via self-hosted UseSend - **Session Management:** Secure cookie-based sessions ### Next.js App - **App Router:** Next.js 16 with React Server Components - **Data Preloading:** Server-side data fetching with Convex - **Middleware:** Route protection & authentication - **Styling:** Tailwind CSS v4 with dark mode - **Analytics:** Plausible (privacy-focused) - **Monitoring:** Sentry error tracking ### Backend - **Real-time:** Convex reactive queries - **File Storage:** Built-in file upload/storage - **Auth:** Multi-provider authentication - **Type-safe:** Full TypeScript with generated types - **Self-hosted:** Complete control over your data ### Developer Experience - **Monorepo:** Turborepo for efficient builds - **Type Safety:** Strict TypeScript throughout - **Code Quality:** ESLint + Prettier with auto-fix - **Hot Reload:** Fast refresh for all packages - **Catalog Deps:** Centralized version management --- ## Deployment ### Docker (Recommended) Build and deploy with Docker Compose: ```bash cd docker/ # Start all services docker compose up -d # View logs docker compose logs -f # Stop services docker compose down ``` **Services:** - `next-app` - Next.js standalone build - `convex-backend` - Convex backend (port 3210) - `convex-dashboard` - Admin dashboard (port 6791) **Network:** Uses `nginx-bridge` network (configurable in `compose.yml`). ### Production Checklist - [ ] Update environment variables in `docker/.env` - [ ] Generate `CONVEX_SELF_HOSTED_ADMIN_KEY` - [ ] Configure reverse proxy (Nginx/Traefik) - [ ] Set up SSL certificates - [ ] Sync auth environment variables to Convex - [ ] Configure backup strategy for `docker/data/` - [ ] Test authentication flow - [ ] Enable Sentry error tracking --- ## Documentation - **[AGENTS.md](./AGENTS.md)** - Comprehensive guide for AI agents & developers - **[Convex Docs](https://docs.convex.dev)** - Official Convex documentation - **[Turborepo Docs](https://turbo.build/repo/docs)** - Turborepo documentation - **[Next.js Docs](https://nextjs.org/docs)** - Next.js documentation --- ## Troubleshooting ### Backend typecheck shows help message This is expected behavior. The backend package follows Convex's structure with only `convex/tsconfig.json` (no root tsconfig). See [AGENTS.md](./AGENTS.md) for details. ### Imports from Convex require .js extension The project uses ESM (`"type": "module"`), requiring explicit file extensions: ```typescript // ✅ Correct // ❌ Wrong import { api } from '@gib/backend/convex/_generated/api'; import { api } from '@gib/backend/convex/_generated/api.js'; ``` ### Docker containers won't start 1. Check Docker logs: `docker compose logs` 2. Verify environment variables in `docker/.env` 3. Ensure ports 3210 and 6791 are available 4. Check network configuration (`nginx-bridge`) --- ## Contributing This is a personal monorepo template. Feel free to fork and adapt for your needs. ### Code Style - Single quotes, trailing commas - 80 character line width - ESLint + Prettier enforced - Import order: Types → React → Next → Third-party → @gib → Local Run `bun lint:fix` and `bun format:fix` before committing. --- ## License MIT --- ## Acknowledgments Built with inspiration from: - [T3 Turbo](https://github.com/t3-oss/create-t3-turbo) - [Convex](https://convex.dev) - [shadcn/ui](https://ui.shadcn.com) - [Turborepo](https://turbo.build)