---
name: next-forge
description: 'next-forge expert guidance — production-grade Turborepo monorepo SaaS starter by Vercel. Use when working in a next-forge project, scaffolding with `npx next-forge init`, or editing @repo/* workspace packages.'
metadata:
  priority: 6
  docs:
    - "https://next-forge.com/docs"
    - "https://github.com/haydenbleasel/next-forge"
  pathPatterns:
    - 'pnpm-workspace.yaml'
    - 'apps/app/**'
    - 'apps/web/**'
    - 'apps/api/**'
    - 'apps/email/**'
    - 'apps/docs/**'
    - 'apps/studio/**'
    - 'apps/storybook/**'
    - 'packages/auth/**'
    - 'packages/database/**'
    - 'packages/design-system/**'
    - 'packages/payments/**'
    - 'packages/email/**'
    - 'packages/analytics/**'
    - 'packages/observability/**'
    - 'packages/security/**'
    - 'packages/ai/**'
    - 'packages/cms/**'
    - 'packages/collaboration/**'
    - 'packages/feature-flags/**'
    - 'packages/internationalization/**'
    - 'packages/notifications/**'
    - 'packages/rate-limit/**'
    - 'packages/seo/**'
    - 'packages/storage/**'
    - 'packages/webhooks/**'
    - 'packages/next-config/**'
    - 'packages/typescript-config/**'
    - '**/keys.ts'
    - '**/env.ts'
    - '**/proxy.ts'
    - 'biome.jsonc'
  bashPatterns:
    - '\bnext-forge\b'
    - '\bnpx\s+next-forge\b'
    - '\bpnpm\s+migrate\b'
    - '\bpnpm\s+bump-deps\b'
    - '\bpnpm\s+bump-ui\b'
    - '\bprisma\s+(generate|db\s+push|format|studio)\b'
    - '\bstripe\s+listen\b'
    - '\bnpx\s+shadcn@latest\s+add\b.*-c\s+packages/design-system\b'
  importPatterns:
    - '@repo/auth'
    - '@repo/database'
    - '@repo/design-system'
    - '@repo/payments'
    - '@repo/email'
    - '@repo/analytics'
    - '@repo/observability'
    - '@repo/security'
    - '@repo/ai'
    - '@repo/cms'
    - '@repo/collaboration'
    - '@repo/feature-flags'
    - '@repo/internationalization'
    - '@repo/notifications'
    - '@repo/rate-limit'
    - '@repo/seo'
    - '@repo/storage'
    - '@repo/webhooks'
    - '@repo/next-config'
    - '@t3-oss/env-nextjs'
    - '@rescale/nemo'
  promptSignals:
    phrases:
      - 'next-forge'
      - 'next forge'
      - '@repo/'
    allOf:
      -
        - 'monorepo'
        - 'saas'
        - 'starter'
      -
        - 'turborepo'
        - 'clerk'
        - 'stripe'
    anyOf:
      - 'saas starter'
      - 'production monorepo'
      - 'keys.ts'
      - 'pnpm-workspace'
    noneOf:
      - 'create-t3-app'
    minScore: 6
category: backend
---

# next-forge

You are an expert in next-forge v5 — a production-grade Turborepo monorepo starter for SaaS applications, created by Vercel. It wires together 20+ packages (auth, database, payments, email, analytics, observability, security, AI, and more) into a cohesive, deploy-ready monorepo.

## Monorepo Structure

```
├── apps/
│   ├── app/          # Main SaaS app (port 3000) — Clerk auth, route groups
│   ├── web/          # Marketing site (port 3001) — blog, pricing, i18n
│   ├── api/          # API server (port 3002) — webhooks, cron jobs
│   ├── email/        # React Email preview (port 3003)
│   ├── docs/         # Mintlify docs
│   ├── studio/       # Prisma Studio
│   └── storybook/    # Component dev (port 6006)
├── packages/
│   ├── ai/               # @repo/ai — AI SDK + OpenAI
│   ├── analytics/        # @repo/analytics — PostHog + GA + Vercel Analytics
│   ├── auth/             # @repo/auth — Clerk
│   ├── cms/              # @repo/cms — BaseHub
│   ├── collaboration/    # @repo/collaboration — Liveblocks
│   ├── database/         # @repo/database — Prisma + Neon
│   ├── design-system/    # @repo/design-system — shadcn/ui + Geist
│   ├── email/            # @repo/email — Resend + React Email
│   ├── feature-flags/    # @repo/feature-flags — Vercel Flags SDK
│   ├── internationalization/ # @repo/internationalization — next-international
│   ├── next-config/      # @repo/next-config — shared Next.js config
│   ├── notifications/    # @repo/notifications — Knock
│   ├── observability/    # @repo/observability — Sentry + BetterStack
│   ├── payments/         # @repo/payments — Stripe
│   ├── rate-limit/       # @repo/rate-limit — Upstash Redis
│   ├── security/         # @repo/security — Arcjet + Nosecone
│   ├── seo/              # @repo/seo — metadata + JSON-LD
│   ├── storage/          # @repo/storage — Vercel Blob
│   ├── typescript-config/ # @repo/typescript-config
│   └── webhooks/         # @repo/webhooks — Svix
├── turbo.json
├── pnpm-workspace.yaml
└── biome.jsonc           # Biome via ultracite
```

**Key principle**: Packages are self-contained — they do not depend on each other. Apps compose packages.

## Getting Started

```bash
npx next-forge@latest init     # Scaffold project (interactive)
# Post-install:
pnpm migrate                   # prisma format + generate + db push
pnpm dev                       # Start all apps via turbo
```

**Minimum env vars to run locally**: `DATABASE_URL` + Clerk keys + app URLs. Everything else is optional.

## Workspace Imports (@repo/*)

All packages use `@repo/*` workspace protocol with specific subpath exports:

```ts
// Auth
import { auth } from "@repo/auth/server";
import { ClerkProvider } from "@repo/auth/provider";
import { currentUser } from "@repo/auth/server";

// Database
import { database } from "@repo/database";

// Design System
import { Button } from "@repo/design-system/components/ui/button";
import { DesignSystemProvider } from "@repo/design-system";
import { fonts } from "@repo/design-system/lib/fonts";

// Payments
import { stripe } from "@repo/payments";

// Email
import { resend } from "@repo/email";

// Observability
import { log } from "@repo/observability/log";
import { captureException } from "@repo/observability/error";

// Analytics
import { AnalyticsProvider } from "@repo/analytics/provider";

// Security
import { secure } from "@repo/security";

// Feature Flags
import { createFlag } from "@repo/feature-flags";

// SEO
import { createMetadata } from "@repo/seo/metadata";
import { JsonLd } from "@repo/seo/json-ld";

// Storage
import { put } from "@repo/storage";

// AI
import { models } from "@repo/ai/lib/models";
```

## Environment Variables

### Type-safe env validation

Every package has a `keys.ts` using `@t3-oss/env-nextjs` + Zod. Apps compose them in `env.ts`:

```ts
// apps/app/env.ts
import { createEnv } from "@t3-oss/env-nextjs";
import { auth } from "@repo/auth/keys";
import { database } from "@repo/database/keys";
import { payments } from "@repo/payments/keys";
export const env = createEnv({ extends: [auth(), database(), payments()] });
```

### Env file locations

| File | Purpose |
|------|---------|
| `apps/app/.env.local` | Main app env vars |
| `apps/web/.env.local` | Marketing site |
| `apps/api/.env.local` | API server |
| `packages/database/.env` | `DATABASE_URL` |

### Required env vars (minimum)

| Var | Package | Required for |
|-----|---------|-------------|
| `DATABASE_URL` | database | Any database access |
| `CLERK_SECRET_KEY` | auth | Authentication |
| `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` | auth | Client-side auth |
| `NEXT_PUBLIC_APP_URL` | — | Cross-app linking |
| `NEXT_PUBLIC_WEB_URL` | — | Cross-app linking |
| `NEXT_PUBLIC_API_URL` | — | Cross-app linking |

### Optional service env vars

| Service | Vars |
|---------|------|
| Stripe | `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET` |
| Resend | `RESEND_TOKEN`, `RESEND_FROM` |
| PostHog | `NEXT_PUBLIC_POSTHOG_KEY`, `NEXT_PUBLIC_POSTHOG_HOST` |
| Sentry | `NEXT_PUBLIC_SENTRY_DSN`, `SENTRY_ORG`, `SENTRY_PROJECT` |
| BetterStack | `BETTERSTACK_API_KEY`, `BETTERSTACK_URL` |
| BaseHub | `BASEHUB_TOKEN` |
| Arcjet | `ARCJET_KEY` |
| Liveblocks | `LIVEBLOCKS_SECRET` |
| Knock | `KNOCK_SECRET_API_KEY`, `NEXT_PUBLIC_KNOCK_API_KEY` |
| Upstash | `UPSTASH_REDIS_REST_URL`, `UPSTASH_REDIS_REST_TOKEN` |
| Vercel Blob | `BLOB_READ_WRITE_TOKEN` |
| Svix | `SVIX_TOKEN` |
| OpenAI | `OPENAI_API_KEY` |
| Feature Flags | `FLAGS_SECRET` |

## Middleware / Proxy Pattern

next-forge uses `proxy.ts` (Next.js 16+), NOT `middleware.ts`:

```ts
// apps/app/proxy.ts — Clerk auth + Nosecone security
import { clerkMiddleware } from "@clerk/nextjs/server";
import { createMiddleware as createNosecone } from "@nosecone/next";
export default clerkMiddleware(createNosecone());
```

```ts
// apps/web/proxy.ts — Clerk + i18n + Arcjet + Nosecone, composed with nemo
import { compose } from "@rescale/nemo";
export default compose([clerkMiddleware, i18nMiddleware, arcjetMiddleware, noseconeMiddleware]);
```

## Database (Prisma + Neon)

- Schema: `packages/database/prisma/schema.prisma`
- Client: `import { database } from "@repo/database"`
- Config: `packages/database/prisma.config.ts` (Neon adapter)
- Commands: `pnpm migrate` (format + generate + db push)
- Studio: `apps/studio` (Prisma Studio)

## Key Commands

| Command | Purpose |
|---------|---------|
| `pnpm dev` | Start all apps |
| `pnpm dev --filter app` | Start single app |
| `pnpm build` | Build all |
| `pnpm migrate` | Prisma format + generate + db push |
| `pnpm bump-deps` | Update all dependencies |
| `pnpm bump-ui` | Update shadcn/ui components |
| `pnpm run boundaries` | Check Turborepo boundaries |
| `npx next-forge@latest update` | Update next-forge (diff-based) |
| `npx shadcn@latest add <comp> -c packages/design-system` | Add UI component |
| `stripe listen --forward-to localhost:3002/webhooks/payments` | Local Stripe webhooks |

## Deployment to Vercel

Deploy as **3 separate Vercel projects** (app, api, web), each with Root Directory set to `apps/<name>`:

1. Create project → set Root Directory to `apps/app`
2. Add environment variables (use Team Environment Variables to avoid duplication)
3. Repeat for `apps/api` and `apps/web`

Recommended subdomains: `app.yourdomain.com`, `api.yourdomain.com`, `www.yourdomain.com`

## API App Patterns

```
apps/api/
├── app/
│   ├── cron/           # Cron jobs (GET handlers)
│   │   └── keep-alive/route.ts
│   ├── webhooks/       # Inbound webhooks
│   │   ├── auth/route.ts      # Clerk webhooks
│   │   └── payments/route.ts  # Stripe webhooks
│   └── health/route.ts
└── vercel.json         # Cron schedules
```

## Design System

- shadcn/ui (New York style, neutral palette)
- Geist Sans + Geist Mono fonts
- Tailwind CSS v4 + tw-animate-css
- Components at `packages/design-system/components/ui/`
- Add components: `npx shadcn@latest add <name> -c packages/design-system`

## Common Gotchas

1. **Env vars are validated at build time** — optional services still require env vars if the package is imported. Remove the import or provide a value.
2. **Multiple .env file locations** — each app and the database package have separate env files. There is no single root `.env`.
3. **`pnpm migrate` before first run** — without this, you get "table does not exist" errors.
4. **Clerk webhooks cannot be tested locally** — need a staging deployment.
5. **Heavy middleware imports** → edge function >1MB on Vercel. Keep proxy.ts imports light.
6. **Prisma v7**: use `--config` not `--schema` for `prisma studio`.
7. **next-forge is a boilerplate, not a library** — updates via `npx next-forge update` need manual merge with your changes.
8. **`turbo.json` globalEnv** — when adding new env vars used at build time, declare them in `turbo.json` `globalEnv` or they won't invalidate cache.

## Removing Optional Services

To remove an unused service (e.g., Stripe, BaseHub, Liveblocks):
1. Delete the package directory (`packages/<service>/`)
2. Remove all `@repo/<service>` imports from apps
3. Remove the `keys()` call from each app's `env.ts`
4. Remove the workspace entry from `pnpm-workspace.yaml` if needed
5. Run `pnpm install` to clean lockfile

## Migration Alternatives

| Category | Default | Alternatives |
|----------|---------|-------------|
| Auth | Clerk | Auth.js, Better Auth, Supabase Auth |
| Database | Prisma + Neon | Drizzle, Supabase, PlanetScale, Turso |
| Payments | Stripe | Lemon Squeezy, Paddle |
| CMS | BaseHub | Content Collections |
| Docs | Mintlify | Fumadocs |
| Feature Flags | Vercel Flags | Hypertune |
| Storage | Vercel Blob | UploadThing |
| Formatting | Biome | ESLint |

## Cross-references

=> skill: turborepo — Monorepo configuration, caching, remote cache
=> skill: auth — Clerk setup, middleware patterns, sign-in/up flows
=> skill: payments — Stripe integration, webhooks, pricing
=> skill: email — Resend + React Email templates
=> skill: shadcn — shadcn/ui components, theming, CLI
=> skill: observability — Sentry + logging setup
=> skill: vercel-storage — Blob, Neon, Upstash
=> skill: vercel-flags — Feature flags with Vercel Flags SDK
=> skill: ai-sdk — AI SDK integration
=> skill: bootstrap — Project bootstrapping flow

## Official Documentation

- https://docs.next-forge.com
- https://github.com/vercel/next-forge
