|  | 
|  | 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: `dev@payloadcms.com` / `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