next-forge
$
npx mdskill add openai/plugins/next-forgeGenerate production-ready Turborepo monorepos instantly.
- Scaffolds complete SaaS applications with integrated workspace packages.
- Integrates with pnpm, Prisma, Stripe, and Vercel tools.
- Analyzes file paths and command patterns to suggest relevant modules.
- Delivers ready-to-deploy codebases with configured environment files.
SKILL.md
.github/skills/next-forgeView on GitHub ↗
---
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
---
# 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