A Turborepo monorepo for building Payload CMS applications with Next.js, TypeScript, and Tailwind CSS v4. Includes two Payload templates and a shared Storybook component library.
.
├── apps/
│ ├── storybook/ # Storybook v9 component explorer (port 6006)
│ └── templates/
│ ├── payload-app-template/ # Payload CMS + custom admin navigation
│ └── payload-blank-template/ # Minimal Payload CMS starter
├── packages/
│ ├── ui/ # Shared React component library (@repo/ui)
│ ├── eslint-config/ # Shared ESLint configurations (@repo/eslint-config)
│ └── typescript-config/ # Shared TypeScript configurations (@repo/typescript-config)
├── .husky/ # Git hooks (lint-staged, commitlint)
├── turbo.json # Turborepo pipeline config
└── package.json # Root workspace config
- Turborepo v2 — monorepo build system with task caching
- Next.js 15 — React framework (App Router)
- Payload CMS v3 — headless CMS with built-in admin
- TypeScript — full type safety across all apps/packages
- Tailwind CSS v4 — utility-first styling
- Storybook v9 — component documentation and visual testing
- pnpm v9 — fast, disk-efficient package manager
Storybook v9 instance that consumes the @repo/ui shared component library. Used to develop, document, and visually test UI components in isolation.
- Port:
6006 - Framework:
@storybook/nextjs-vite - Testing: Vitest + Playwright (via
@storybook/addon-vitest) - Visual regression: Chromatic integration
Minimal Payload CMS starter — the cleanest possible foundation to build from.
Includes:
- Payload CMS v3 with MongoDB adapter
- Next.js App Router with
(frontend)and(payload)route groups Userscollection (auth-enabled, admin access)Mediacollection (uploads with image resizing via sharp)- Lexical rich text editor
- Payload Cloud plugin
- Docker Compose for local MongoDB
- GraphQL endpoint
Use this when: you want a clean slate with no opinions beyond the Payload essentials.
Full-featured Payload CMS template with custom admin UI customization. Extends the blank template with a custom admin navigation component.
Everything in blank template, plus:
- Custom
AdminNavbarcomponent replacing Payload's default nav- Collapsible hamburger menu
- Nav icon mapping
- Client/server split for performance
- Pre-wired component override in
payload.config.tsviaadmin.components.Nav
Use this when: you want a starting point for an app that needs a branded or heavily customized Payload admin panel.
| Feature | payload-blank-template |
payload-app-template |
|---|---|---|
| Custom admin nav | — | ✓ (AdminNavbar) |
| Nav hamburger toggle | — | ✓ |
| Component overrides example | — | ✓ |
| Collections (Users, Media) | ✓ | ✓ |
| MongoDB + Mongoose adapter | ✓ | ✓ |
| Lexical editor | ✓ | ✓ |
| Docker Compose | ✓ | ✓ |
| GraphQL | ✓ | ✓ |
Shared React component library built with Tailwind CSS v4 and Radix UI primitives. Consumed by both Storybook and any app in the monorepo.
- Components, hooks, and utilities exported from
packages/ui/src/ - Exports global CSS and PostCSS config for Tailwind setup
- Built on
@radix-ui/react-slot,clsx,tailwind-merge,class-variance-authority,lucide-react,next-themes,zod
Shared ESLint configurations. Provides configs for:
./base— base rules./next— Next.js apps./payload— Payload CMS apps./react-internal— internal React packages
Shared tsconfig base files:
base.json— generic TypeScript confignextjs.json— Next.js app configreact-library.json— React component library config
- Node.js >= 18
- pnpm >= 9.0.0
pnpm install# Run all apps (storybook + any non-template apps)
pnpm dev
# Run only Storybook
pnpm dev:storybook
# Run a specific Payload template
pnpm dev:template:blank
pnpm dev:template:app
# Run everything including templates
pnpm dev:all# Build all non-template apps
pnpm buildpnpm lint # Lint all workspaces
pnpm lint:fix # Lint and auto-fix
pnpm check-types # TypeScript type checking
pnpm format # Prettier format
pnpm format:check # Check formatting
pnpm test # Unit tests
pnpm test:e2e # End-to-end tests (Playwright)Templates live in apps/templates/ and are intentionally excluded from the monorepo's default build/dev/test pipelines. They are standalone Payload CMS apps meant to be copied and used as the starting point for a new workspace.
Use Turborepo's built-in generator to copy any existing workspace:
# Interactive — pick any workspace to copy
turbo gen workspace --copy
# Copy the blank Payload template
turbo gen workspace --copy payload-blank-template
# Copy the full app template
turbo gen workspace --copy payload-app-template
You will be prompted for the new workspace name and destination. The generator copies all files and updates package.json names automatically.
turbo gen workspacecd apps/<your-new-app>cp .env.example .env- Set
DATABASE_URIandPAYLOAD_SECRETin.env - Start MongoDB — either locally or via Docker:
docker-compose up -d
pnpm dev(from the repo root, filtered to your app):turbo dev --filter=<your-app-name>
- Open
http://localhost:3000/adminto create your first admin user.
cd apps/<your-new-storybook>- Update the
@repo/uidependency if you've renamed the UI package, or point it at your own component library. pnpm devfrom the root, or:turbo dev --filter=<your-storybook-name>
- Open
http://localhost:6006
This project uses Conventional Commits:
feat: add new feature
fix: bug fix
docs: documentation changes
style: code formatting
refactor: code refactoring
test: add or update tests
chore: maintenance tasks
ci: CI/CD changes
- pre-commit: runs lint-staged (Prettier formatting)
- pre-push: runs type checking and tests