2026-01-14 00:33:38 -06:00
2026-01-14 00:33:38 -06:00
2026-01-13 16:24:58 -06:00
2026-01-14 00:33:38 -06:00
2026-01-14 00:33:38 -06:00
2025-10-29 09:02:41 -05:00
2026-01-13 11:11:22 -06:00
2026-01-14 00:33:38 -06:00
2026-01-14 00:33:38 -06:00
2026-01-13 11:11:22 -06:00

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 (v1.2.19+)
  • Docker & Docker Compose (for self-hosted Convex)
  • Node.js 22.20.0+ (for compatibility)

Development Setup

1. Clone & Install

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:

# 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:

cd docker/
cp .env.example .env
# Edit .env with your configuration

4. Start Self-Hosted Convex

Spin up the Convex backend and dashboard:

cd docker/
docker compose up -d convex-backend convex-dashboard

Services:

5. Generate Auth Keys & Sync Environment Variables

Generate JWT keys for Convex Auth:

cd packages/backend
bun run scripts/generateKeys.mjs

Sync environment variables to Convex deployment (via CLI or Dashboard):

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

# From project root
bun dev:next          # Next.js app + Convex backend
# or
bun dev               # All apps (Next.js + Expo + Backend)

App URLs:


Development Commands

# 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:

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

Build and deploy with Docker Compose:

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


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 for details.

Imports from Convex require .js extension

The project uses ESM ("type": "module"), requiring explicit file extensions:

// ✅ 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:

Description
Convex Monorepo with Next.js & Expo
Readme 3.5 MiB
Languages
TypeScript 90%
JavaScript 5%
CSS 4%
Handlebars 0.5%
Dockerfile 0.5%