Update README.md
This commit is contained in:
429
README.md
429
README.md
@@ -1,138 +1,359 @@
|
||||
# Turborepo starter
|
||||
# Convex Turbo Monorepo
|
||||
|
||||
This Turborepo starter is maintained by Gib.
|
||||
A production-ready Turborepo starter with Next.js, Expo, and self-hosted Convex backend. Built with TypeScript, Tailwind CSS, and modern tooling.
|
||||
|
||||
## Using this example
|
||||
---
|
||||
|
||||
Run the following command:
|
||||
## What's Inside?
|
||||
|
||||
```sh
|
||||
npx create-turbo@latest -e https://git.gbrown.org/gib/convex-monorepo.git
|
||||
### 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
|
||||
```
|
||||
|
||||
## What's inside?
|
||||
#### 2. Configure Environment Variables
|
||||
|
||||
This Turborepo includes the following packages/apps:
|
||||
Create a `.env` file in the project root with the following variables:
|
||||
|
||||
### Apps and Packages
|
||||
```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`: a [Next.js](https://nextjs.org/) app
|
||||
- `expo`: another [Next.js](https://nextjs.org/) app
|
||||
- `@gib/backend`: a [Convex](https://convex.dev) Backend
|
||||
- `@gib/ui`: a Shadcn React component library primarily for Next.js (In case we want to add another web application).
|
||||
- `@gib/eslint-config`: `eslint` configurations (includes `eslint-config-next` and `eslint-config-prettier`)
|
||||
- `@gib/prettier-config`: Prettier configurations
|
||||
- `@gib/tailwind-config`: Tailwind configurations
|
||||
- `@gib/typescript-config`: `tsconfig.json`s used throughout the monorepo
|
||||
# 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=
|
||||
|
||||
Each package/app is 100% [TypeScript](https://www.typescriptlang.org/).
|
||||
# Server-side
|
||||
SENTRY_AUTH_TOKEN=
|
||||
|
||||
### Utilities
|
||||
|
||||
This Turborepo has some additional tools already setup for you:
|
||||
|
||||
- [TypeScript](https://www.typescriptlang.org/) for static type checking
|
||||
- [ESLint](https://eslint.org/) for code linting
|
||||
- [Prettier](https://prettier.io) for code formatting
|
||||
|
||||
### Build
|
||||
|
||||
To build all apps and packages, run the following command:
|
||||
|
||||
```
|
||||
cd my-turborepo
|
||||
|
||||
# With [global `turbo`](https://turborepo.com/docs/getting-started/installation#global-installation) installed (recommended)
|
||||
turbo build
|
||||
|
||||
# Without [global `turbo`](https://turborepo.com/docs/getting-started/installation#global-installation), use your package manager
|
||||
npx turbo build
|
||||
yarn dlx turbo build
|
||||
pnpm exec turbo build
|
||||
# Auth (will be synced to Convex)
|
||||
AUTH_AUTHENTIK_ID=
|
||||
AUTH_AUTHENTIK_SECRET=
|
||||
AUTH_AUTHENTIK_ISSUER=
|
||||
USESEND_API_KEY=
|
||||
```
|
||||
|
||||
You can build a specific package by using a [filter](https://turborepo.com/docs/crafting-your-repository/running-tasks#using-filters):
|
||||
**For local development:** Use `http://localhost:3210` for Convex URLs.
|
||||
|
||||
```
|
||||
# With [global `turbo`](https://turborepo.com/docs/getting-started/installation#global-installation) installed (recommended)
|
||||
turbo build --filter=docs
|
||||
#### 3. Configure Docker Environment
|
||||
|
||||
# Without [global `turbo`](https://turborepo.com/docs/getting-started/installation#global-installation), use your package manager
|
||||
npx turbo build --filter=docs
|
||||
yarn exec turbo build --filter=docs
|
||||
pnpm exec turbo build --filter=docs
|
||||
Check and update environment variables in `docker/.env` for your deployment:
|
||||
|
||||
```bash
|
||||
cd docker/
|
||||
cp .env.example .env
|
||||
# Edit .env with your configuration
|
||||
```
|
||||
|
||||
### Develop
|
||||
#### 4. Start Self-Hosted Convex
|
||||
|
||||
To develop all apps and packages, run the following command:
|
||||
Spin up the Convex backend and dashboard:
|
||||
|
||||
```
|
||||
cd my-turborepo
|
||||
|
||||
# With [global `turbo`](https://turborepo.com/docs/getting-started/installation#global-installation) installed (recommended)
|
||||
turbo dev
|
||||
|
||||
# Without [global `turbo`](https://turborepo.com/docs/getting-started/installation#global-installation), use your package manager
|
||||
npx turbo dev
|
||||
yarn exec turbo dev
|
||||
pnpm exec turbo dev
|
||||
```bash
|
||||
cd docker/
|
||||
docker compose up -d convex-backend convex-dashboard
|
||||
```
|
||||
|
||||
You can develop a specific package by using a [filter](https://turborepo.com/docs/crafting-your-repository/running-tasks#using-filters):
|
||||
**Services:**
|
||||
|
||||
```
|
||||
# With [global `turbo`](https://turborepo.com/docs/getting-started/installation#global-installation) installed (recommended)
|
||||
turbo dev --filter=web
|
||||
- **Backend:** http://localhost:3210
|
||||
- **Dashboard:** http://localhost:6791
|
||||
|
||||
# Without [global `turbo`](https://turborepo.com/docs/getting-started/installation#global-installation), use your package manager
|
||||
npx turbo dev --filter=web
|
||||
yarn exec turbo dev --filter=web
|
||||
pnpm exec turbo dev --filter=web
|
||||
#### 5. Generate Auth Keys & Sync Environment Variables
|
||||
|
||||
Generate JWT keys for Convex Auth:
|
||||
|
||||
```bash
|
||||
cd packages/backend
|
||||
bun run scripts/generateKeys.mjs
|
||||
```
|
||||
|
||||
### Remote Caching
|
||||
Sync environment variables to Convex deployment (via CLI or Dashboard):
|
||||
|
||||
> [!TIP]
|
||||
> Vercel Remote Cache is free for all plans. Get started today at [vercel.com](https://vercel.com/signup?/signup?utm_source=remote-cache-sdk&utm_campaign=free_remote_cache).
|
||||
|
||||
Turborepo can use a technique known as [Remote Caching](https://turborepo.com/docs/core-concepts/remote-caching) to share cache artifacts across machines, enabling you to share build caches with your team and CI/CD pipelines.
|
||||
|
||||
By 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?utm_source=turborepo-examples), then enter the following commands:
|
||||
|
||||
```
|
||||
cd my-turborepo
|
||||
|
||||
# With [global `turbo`](https://turborepo.com/docs/getting-started/installation#global-installation) installed (recommended)
|
||||
turbo login
|
||||
|
||||
# Without [global `turbo`](https://turborepo.com/docs/getting-started/installation#global-installation), use your package manager
|
||||
npx turbo login
|
||||
yarn exec turbo login
|
||||
pnpm exec turbo login
|
||||
```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"
|
||||
```
|
||||
|
||||
This will authenticate the Turborepo CLI with your [Vercel account](https://vercel.com/docs/concepts/personal-accounts/overview).
|
||||
**Important:** For local development, set `CONVEX_SITE_URL` to `http://localhost:3000`.
|
||||
|
||||
Next, you can link your Turborepo to your Remote Cache by running the following command from the root of your Turborepo:
|
||||
#### 6. Start Development Server
|
||||
|
||||
```
|
||||
# With [global `turbo`](https://turborepo.com/docs/getting-started/installation#global-installation) installed (recommended)
|
||||
turbo link
|
||||
|
||||
# Without [global `turbo`](https://turborepo.com/docs/getting-started/installation#global-installation), use your package manager
|
||||
npx turbo link
|
||||
yarn exec turbo link
|
||||
pnpm exec turbo link
|
||||
```bash
|
||||
# From project root
|
||||
bun dev:next # Next.js app + Convex backend
|
||||
# or
|
||||
bun dev # All apps (Next.js + Expo + Backend)
|
||||
```
|
||||
|
||||
## Useful Links
|
||||
**App URLs:**
|
||||
|
||||
Learn more about the power of Turborepo:
|
||||
- **Next.js:** http://localhost:3000
|
||||
- **Convex Dashboard:** http://localhost:6791
|
||||
|
||||
- [Tasks](https://turborepo.com/docs/crafting-your-repository/running-tasks)
|
||||
- [Caching](https://turborepo.com/docs/crafting-your-repository/caching)
|
||||
- [Remote Caching](https://turborepo.com/docs/core-concepts/remote-caching)
|
||||
- [Filtering](https://turborepo.com/docs/crafting-your-repository/running-tasks#using-filters)
|
||||
- [Configuration Options](https://turborepo.com/docs/reference/configuration)
|
||||
- [CLI Usage](https://turborepo.com/docs/reference/command-line-reference)
|
||||
---
|
||||
|
||||
## 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)
|
||||
|
||||
Reference in New Issue
Block a user