Skip to content
Agentmart
Submit a tool

AGENTS.md · payloadcms/payload

AGENTS.md from payloadcms/payload: 487 lines covering Project Structure, Quick Start, Build Commands, Development and more.

Template by payloadcms

IndexedMIT★ 45,465
Write a review

Install

Works with Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code. Read the repository before you give any tool access to your data.

curl -fsSL https://raw.githubusercontent.com/payloadcms/payload/main/AGENTS.md -o AGENTS.md

Read it and adapt it to your project before use.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

The AGENTS.md file that payloadcms/payload (45,464 stars) keeps for coding agents. It has 487 lines in 10 sections: Project Structure; Quick Start; Build Commands; Development; Testing; Linting & Formatting; Internationalization; Commit & PR Guidelines; Additional Resources; Admin Panel. Use it as a model for your own project's instructions.

Use cases: prompt-engineering

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

What's in it

An AGENTS.md file: instructions coding agents (Codex, Cursor, Copilot, Gemini CLI and others) read before working in a repo.

For
Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code
Length
487 lines
File
AGENTS.md

Sections

  1. Project Structure
  2. Quick Start
  3. Build Commands
  4. Development
  5. Testing
  6. Linting & Formatting
  7. Internationalization
  8. Commit & PR Guidelines
  9. Additional Resources
  10. Admin Panel

First lines (shown under the repo's MIT license)

# AGENTS.md

## Project Structure

Payload is a monorepo structured around Next.js, containing the core CMS platform, database adapters, plugins, and tooling.

### Key Directories

- `packages/` - All publishable packages
  - `packages/payload` - Core Payload package containing the main CMS logic
  - `packages/ui` - Admin UI components (React Server Components)
  - `packages/next` - Next.js integration layer
  - `packages/db-*` - Database adapters (MongoDB, Postgres, SQLite, Vercel Postgres, D1 SQLite)
  - `packages/drizzle` - Drizzle ORM integration
  - `packages/kv-redis` - Redis key-value store adapter
  - `packages/richtext-*` - Rich text editors (Lexical)
  - `packages/storage-*` - Storage adapters (S3, Azure, GCS, Vercel Blob, R2)
  - `packages/email-*` - Email adapters (Nodemailer, Resend)
  - `packages/plugin-*` - Additional functionality plugins
  - `packages/graphql` - GraphQL API layer
  - `packages/translations` - i18n translations
- `test/` - Test suites organized by feature area. Each directory contains a granular Payload config and test files
- `docs/` - Documentation (deployed to payloadcms.com)
- `tools/` - Monorepo tooling
- `templates/` - Production-ready project templates
- `examples/` - Example implementations

### Architecture Notes

- Payload 3.x is built as a Next.js native CMS that installs directly in `/app` folder
- UI is built with React Server Components (RSC)
- Database adapters use Drizzle ORM under the hood
- Packages use TypeScript with strict mode and path mappings defined in `tsconfig.base.json`
- Source files are in `src/`, compiled outputs go to `dist/`
- Monorepo uses pnpm workspaces and Turbo for builds

## Quick Start

1. `pnpm install`
2. `pnpm run build:core`
3. `pnpm run dev` (MongoDB) or `pnpm run dev:postgres`

## Build Commands

- `pnpm install` - Install all dependencies
- `pnpm turbo` - All Turbo commands should be run from root with pnpm - not with `turbo` directly
- `pnpm run build` or `pnpm run build:core` - Build core packages (excludes plugins and storage adapters)
- `pnpm run build:all` - Build all packages
- `pnpm run build:<directory_name>` - Build specific package (e.g. `pnpm run build:db-mongodb`, `pnpm run build:ui`)

## Development

### Coding Patterns and Best Practices

- Always use object parameters for function arguments: `fn({ name }: { name: string })` not `fn(name: string)` (improves backwards-compatibility)
- Prefer types over interfaces (except when extending external types)
- Prefer functions over classes (classes only for errors/adapters)
- Prefer pure functions; when mutation is unavoidable, return the mutated object instead of void.
- Organize functions top-down: exports before helpers
- Use JSDoc for complex functions; add tags only when justified beyond type signature
- Use `import type` for types, regular `import` for values, separate statements even from same module
- Prefix booleans with `is`/`has`/`can`/`should` (e.g., `isValid`, `hasData`) for clarity
- Prefer self describing function and variable names over generic names with comments to explain their purpose
- For changes affecting rendered UI, user interaction, focus, keyboard behavior, content, or component semantics, use the `payload-accessibility` skill and report the WCAG 2.2 Level A and AA criteria assessed, automated evidence, and any required manual or assistive-technology verification.
- **Translation/Label handling**: Always use `getTranslation` from `@payloadcms/translations` when you need to render labels defined in the config - it already handles functions, strings, and translation objects correctly. Don't write custom if/else logic to handle different label types.
- **Memoize arrays/objects passed to hooks**: Never pass inline array/object literals to custom hooks - they create new references on every render, breaking memoization and causing unnecessary re-renders or remounts.

  ```typescript
  // BAD - creates new array every render, breaks hook memoization
  const [Drawer] = useHierarchyDrawer({
    filterByCollection: [collectionSlug],
  })

  // GOOD - memoized, stable reference
  const filterByCollection = useMemo(() => [collectionSlug], [collectionSlug])
  const [Drawer] = useHierarchyDrawer({
    filterByCollection,
  })
  ```

- Commenting Guidelines

  - Execution flow: Skip comments when code is self-documenting. Keep for complex logic, non-obvious "why", multi-line context, or if following a documented, multi-step flow.
  - Top of file/module: Use sparingly; only for non-obvious purpose/context or an overview of complex logic.
  - Type definitions: Property/interface documentation is always acceptable.

- Logger Usage (`payload.logger.error`)
  - Valid: `payload.logger.error('message')` or `payload.logger.error({ msg: '...', err: error })`
  - Invalid: `payload.logger.error('message', err)` - don't pass error as second argument
  - Use `err` not `error`, use `msg` not `message` in object form

### React Component File Structure

Each React component should have its own named folder:

```
ComponentName/
├── index.tsx       # Component implementation
└── index.css       # Styles (if applicable)
```

- **Do:** Create a folder per component with `index.tsx` and `index.css`
- **Don't:** Place multiple `ComponentName.tsx` files in a single folder with one shared `.css` file
- Re-export from barrel files (`index.ts`) when grouping related components in a parent directory
- New styles should be written in plain CSS, not SCSS - SCSS is being phased out and is no longer linted (see [Writing CSS](#writing-css))

### Running Dev Server

- `pnpm run dev` - Start dev server with default config (`test/_community/config.ts`)
- `pnpm run dev <directory_name>` - Start dev server with specific test config (e.g. `pnpm run dev fields` loads `test/fields/config.ts`)
- `pnpm run dev:postgres` - Run dev server with Postgres

### Running the Payload CLI

`pnpm payload <directory_name> <command> [...args]` runs the real Payload CLI against a test suite config. The first argument selects the test folder (e.g. `pnpm payload fields generate:types` uses `test/fields/config.ts`); everything after it is forwarded to the CLI unchanged. Run `pnpm payload <directory_name>` with no command to list all commands.

### Development Environment

- Auto-login is enabled by default with credentials: `dev@payloadcms.com` / `test`
- To disable: pass `--no-auto-login` flag or set `PAYLOAD_PUBLIC_DISABLE_AUTO_LOGIN=false`
- Default database is MongoDB (in-memory). Switch to Postgres with `PAYLOAD_DATABASE=postgres`
- Docker services: `pnpm docker:start` / `pnpm docker:clean` / `pnpm docker:test`

### Playwright MCP

You should have access to the Playwright MCP server. This MCP server enables LLMs to interact with web pages through structured accessibility snapshots, bypassing the need for screenshots or visually-tuned models.

**Prerequisites:**

- The dev server MUST be running (`pnpm run dev`) before using the MCP
- First call `browser_install` to set up the browser if needed

**Key tools (not exhaustive):**

- `browser_navigate` - Navigate to a URL
- `browser_snapshot` - Get accessibility snapshot of current page
- `browser_click` - Click elements (requires `ref` from snapshot)
- `browser_fill_form` - Fill form fields
- `browser_take_screenshot` - Capture screenshot (use `fullPage: true` for full page)

**Screenshots for visual verification:**

Use `browser_take_screenshot` to visually verify UI state. Useful for:

- Confirming layout and styling look correct
- Checking component rendering (tags, forms, tables)
- Debugging UI issues that aren't visible in accessibility snapshots

```
browser_take_screenshot()                    # Viewport only
browser_take_screenshot({ fullPage: true })  # Full scrollable page
```

Screenshots are saved to `.playwright-mcp/` and displayed inline.

**Usage flow:**

1. Ensure dev server is running on `localhost:3000`
2. Call `browser_navigate` to open a page
3. Call `browser_snapshot` to get element refs

Signals

Stars
45,465
Forks
4,335
Open issues
544
Last commit (this folder)
Oct 21, 2026 (8 days ago)
Last release
Oct 22, 2026 (7 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026
Cite this page

AGENTS.md · payloadcms/payload. Agent Mart. https://agentmart.dev/templates/payloadcms-payload-agents-md (last updated 2026-10-24)