|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Structure |
| 6 | + |
| 7 | +Payload is a monorepo structured around Next.js, containing the core CMS platform, database adapters, plugins, and tooling. |
| 8 | + |
| 9 | +### Key Directories |
| 10 | + |
| 11 | +- `packages/` - All publishable packages |
| 12 | + - `packages/payload` - Core Payload package containing the main CMS logic |
| 13 | + - `packages/ui` - Admin UI components (React Server Components) |
| 14 | + - `packages/next` - Next.js integration layer |
| 15 | + - `packages/db-*` - Database adapters (MongoDB, Postgres, SQLite, Vercel Postgres, D1 SQLite) |
| 16 | + - `packages/drizzle` - Drizzle ORM integration |
| 17 | + - `packages/richtext-*` - Rich text editors (Lexical, Slate) |
| 18 | + - `packages/storage-*` - Storage adapters (S3, Azure, GCS, Uploadthing, Vercel Blob) |
| 19 | + - `packages/email-*` - Email adapters (Nodemailer, Resend) |
| 20 | + - `packages/plugin-*` - Additional functionality plugins |
| 21 | + - `packages/graphql` - GraphQL API layer |
| 22 | + - `packages/translations` - i18n translations |
| 23 | +- `test/` - Test suites organized by feature area. Each directory contains a granular Payload config and test files |
| 24 | +- `docs/` - Documentation (deployed to payloadcms.com) |
| 25 | +- `tools/` - Monorepo tooling |
| 26 | +- `templates/` - Production-ready project templates |
| 27 | +- `examples/` - Example implementations |
| 28 | + |
| 29 | +### Architecture Notes |
| 30 | + |
| 31 | +- Payload 3.x is built as a Next.js native CMS that installs directly in `/app` folder |
| 32 | +- UI is built with React Server Components (RSC) |
| 33 | +- Database adapters use Drizzle ORM under the hood |
| 34 | +- Packages use TypeScript with strict mode and path mappings defined in `tsconfig.base.json` |
| 35 | +- Source files are in `src/`, compiled outputs go to `dist/` |
| 36 | +- Monorepo uses pnpm workspaces and Turbo for builds |
| 37 | + |
| 38 | +## Build Commands |
| 39 | + |
| 40 | +- `pnpm install` - Install all dependencies (pnpm required - run `corepack enable` first) |
| 41 | +- `pnpm build` or `pnpm build:core` - Build core packages (excludes plugins and storage adapters) |
| 42 | +- `pnpm build:all` - Build all packages |
| 43 | +- `pnpm build:<directory_name>` - Build specific package (e.g. `pnpm build:db-mongodb`, `pnpm build:ui`) |
| 44 | + |
| 45 | +## Development |
| 46 | + |
| 47 | +### Running Dev Server |
| 48 | + |
| 49 | +- `pnpm dev` - Start dev server with default config (`test/_community/config.ts`) |
| 50 | +- `pnpm dev <directory_name>` - Start dev server with specific test config (e.g. `pnpm dev fields` loads `test/fields/config.ts`) |
| 51 | +- `pnpm dev:postgres` - Run dev server with Postgres |
| 52 | +- `pnpm dev:memorydb` - Run dev server with in-memory MongoDB |
| 53 | + |
| 54 | +### Development Environment |
| 55 | + |
| 56 | +- Auto-login is enabled by default with credentials: `[email protected]` / `test` |
| 57 | +- To disable: pass `--no-auto-login` flag or set `PAYLOAD_PUBLIC_DISABLE_AUTO_LOGIN=false` |
| 58 | +- Default database is MongoDB (in-memory). Switch to Postgres with `PAYLOAD_DATABASE=postgres` |
| 59 | +- Docker services: `pnpm docker:start` / `pnpm docker:stop` / `pnpm docker:restart` |
| 60 | + |
| 61 | +## Testing |
| 62 | + |
| 63 | +### Running Tests |
| 64 | + |
| 65 | +- `pnpm test` - Run all tests (integration + components + e2e) |
| 66 | +- `pnpm test:int` - Run integration tests (MongoDB, recommended for verifying local changes) |
| 67 | +- `pnpm test:int <directory_name>` - Run specific integration test suite (e.g. `pnpm test:int fields`) |
| 68 | +- `pnpm test:int:postgres` - Run integration tests with Postgres |
| 69 | +- `pnpm test:int:sqlite` - Run integration tests with SQLite |
| 70 | +- `pnpm test:unit` - Run unit tests |
| 71 | +- `pnpm test:e2e` - Run end-to-end tests (Playwright) |
| 72 | +- `pnpm test:e2e:headed` - Run e2e tests in headed mode |
| 73 | +- `pnpm test:e2e:debug` - Run e2e tests in debug mode |
| 74 | +- `pnpm test:components` - Run component tests (Jest) |
| 75 | +- `pnpm test:types` - Run type tests (tstyche) |
| 76 | + |
| 77 | +### Test Structure |
| 78 | + |
| 79 | +Each test directory in `test/` follows this pattern: |
| 80 | + |
| 81 | +``` |
| 82 | +test/<feature-name>/ |
| 83 | +├── config.ts # Lightweight Payload config for testing |
| 84 | +├── int.spec.ts # Integration tests (Jest) |
| 85 | +├── e2e.spec.ts # End-to-end tests (Playwright) |
| 86 | +└── payload-types.ts # Generated types |
| 87 | +``` |
| 88 | + |
| 89 | +Generate types for a test directory: `pnpm dev:generate-types <directory_name>` |
| 90 | + |
| 91 | +## Linting & Formatting |
| 92 | + |
| 93 | +- `pnpm lint` - Run linter across all packages |
| 94 | +- `pnpm lint:fix` - Fix linting issues |
| 95 | + |
| 96 | +## Internationalization |
| 97 | + |
| 98 | +- Translation files are in `packages/translations/src/languages/` |
| 99 | +- Add new strings to English locale first, then translate to other languages |
| 100 | +- Run `pnpm translateNewKeys` to auto-translate new keys (requires `OPENAI_KEY` in `.env`) |
| 101 | +- Lexical translations: `cd packages/richtext-lexical && pnpm translateNewKeys` |
| 102 | + |
| 103 | +## Commit & PR Guidelines |
| 104 | + |
| 105 | +This repository follows [Conventional Commits](https://www.conventionalcommits.org/). |
| 106 | + |
| 107 | +### PR Title Format |
| 108 | + |
| 109 | +`<type>(<scope>): <title>` |
| 110 | + |
| 111 | +- Title must start with lowercase letter |
| 112 | +- Types: `build`, `chore`, `ci`, `docs`, `examples`, `feat`, `fix`, `perf`, `refactor`, `revert`, `style`, `templates`, `test` |
| 113 | +- Prefer `feat` for new features, `fix` for bug fixes |
| 114 | +- Scopes match package names: `db-*`, `richtext-*`, `storage-*`, `plugin-*`, `ui`, `next`, `graphql`, `translations`, etc. |
| 115 | +- Choose most relevant scope if multiple packages modified, or omit scope entirely |
| 116 | + |
| 117 | +Examples: |
| 118 | + |
| 119 | +- `feat(db-mongodb): add support for transactions` |
| 120 | +- `feat(richtext-lexical): add options to hide block handles` |
| 121 | +- `fix(ui): json field type ignoring editorOptions` |
| 122 | +- `feat: add new collection functionality` |
| 123 | + |
| 124 | +### Commit Guidelines |
| 125 | + |
| 126 | +- First commit of branch should follow PR title format |
| 127 | +- Subsequent commits should use `chore` without scope unless specific package is being modified |
| 128 | +- All commits in a PR are squashed on merge using PR title as commit message |
| 129 | + |
| 130 | +## Additional Resources |
| 131 | + |
| 132 | +- LLMS.txt: <https://payloadcms.com/llms.txt> |
| 133 | +- LLMS-FULL.txt: <https://payloadcms.com/llms-full.txt> |
| 134 | +- Node version: ^18.20.2 || >=20.9.0 |
| 135 | +- pnpm version: ^9.7.0 |
0 commit comments