# 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 <your-repo-url>
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=<generated>
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)
