agentleFS
FirzusFirzus/agent-skills/skills/web/payload-cms/SKILL.md

payload-cms

Skill4 starsChanged 20 days agoMITView on GitHub

Payload CMS 3.x, the Next.js-native TypeScript headless CMS. Use when working in payload.config.ts, collections, fields, access control, hooks, the Local API, versions and drafts, database or storage adapters, plugin authoring, or the official MCP plugin.

  • Reads credentials

2 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

8 rules. About 0 are common, 1 is distinctive, and 7 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 7

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Read payload.config.ts (repo root or beside /app) — db, collections, plugins, localization and versions defaults tell you what schema you …

    line 37
  2. Very specific:

    Read the installed versions of payload, next, and the @payloadcms/* packages from package.json and the lockfile.

    line 40
  3. Very specific:

    Check whether @payloadcms/plugin-mcp is configured.

    line 46
  4. Very specific:

    Check the project's next version against that list before blaming Payload for an admin-panel or build failure.

    line 60
  5. Very specific:

    Treat payload-types.ts as build output, and regenerate after any field change before trusting a type error.

    line 92
  6. Very specific:

    Read reference/access-control.md.

    line 135
  7. Very specific:

    Read reference/hooks.md. Two rules carry most failures: calling payload.update() on the document that triggered afterChange loops forever …

    line 145
  8. Distinctive:

    Read reference/extending.md for plugin authoring, custom endpoints, the jobs queue, storage adapters, and localization.

    line 170

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Payload CMS

Payload 3.x runs inside a Next.js (or TanStack Start) app: the config is source code, the admin panel is mounted routes, and the database schema is derived from your collections. Prefer the project's existing conventions, then steer with three leading words: config is the schema, access is opt-in, and thread the request.

Branch-specific references, loaded on demand:

  • reference/collections.md — collection config, auth, uploads, versions and drafts, globals.
  • reference/fields.md — field types, virtual and join fields, the experimental slug field, validation, type guards.
  • reference/access-control.md — collection, field, and admin access; the Access Operation trap.
  • reference/hooks.md — hook families, argument shapes, context, loop prevention.
  • reference/queries.md — operators, depth, select, Local API, transactions.
  • reference/mcp.md — the official @payloadcms/plugin-mcp server, its tools and its three authorization gates.
  • reference/extending.md — plugin authoring, custom endpoints, jobs queue, storage adapters, localization.

First Checks

  1. Read payload.config.ts (repo root or beside /app) — db, collections, plugins, localization and versions defaults tell you what schema you are editing.
  2. Read the installed versions of payload, next, and the @payloadcms/* packages from package.json and the lockfile. Every @payloadcms/* package is versioned in lockstep with core; a mismatch is a real bug source.
  3. Find the database adapter — @payloadcms/db-mongodb, @payloadcms/db-postgres, or @payloadcms/db-sqlite. It decides migration workflow and transaction behaviour.
  4. Check whether @payloadcms/plugin-mcp is configured. If it is, and a running app plus an API key are available, read reference/mcp.md before touching document data by hand.

Done when: config path, Payload version, adapter, and MCP presence are each stated — or their absence is.

The Version Allow-List

Next.js compatibility is a narrow allow-list, not a floor: 15.2.9–15.2.x, 15.3.9–15.3.x, 15.4.11–15.4.x, and 16.2.6+. "Latest Next.js" is not automatically supported. Node 20.9.0+; pnpm, npm, or yarn 2+ — yarn 1 is unsupported, and npm may need --legacy-peer-deps.

Check the project's next version against that list before blaming Payload for an admin-panel or build failure.

Minimal Config

import { buildConfig } from 'payload'
import { sqliteAdapter } from '@payloadcms/db-sqlite'
import { lexicalEditor } from '@payloadcms/richtext-lexical'

export default buildConfig({
  collections: [Posts],
  editor: lexicalEditor(),
  secret: process.env.PAYLOAD_SECRET,
  db: sqliteAdapter({ client: { url: process.env.DATABASE_URI } }),
})

editor is needed only for rich text, sharp only for image manipulation on upload collections, graphql only for the GraphQL API. Lexical is the editor: the Slate-based editor is deprecated and is removed in 4.0, so scaffold Lexical.

tsconfig.json must map "@payload-config": ["./payload.config.ts"] — that path is what import config from '@payload-config' resolves against.

Types Are Generated, Not Written

payload generate:types writes payload-types.ts and registers the types globally through a declare statement. payload build regenerates the import map and the types before delegating to next build / vite build, unless you pass --no-types.

Treat payload-types.ts as build output, and regenerate after any field change before trusting a type error.

Choose The Workflow

Pick one branch. Complete its criterion before claiming the task done.

Shaping the schema

Config is the schema: adding a field changes the database. Read reference/collections.md and reference/fields.md before adding or renaming fields.

With a SQL adapter a schema change needs a migration — check the project's migrations/ folder and its scripts rather than assuming auto-push.

Done when: types are regenerated, the migration situation is stated, and every new field's required / unique / localized choice is deliberate.

Reading or writing documents

Apply access is opt-in: the Local API skips access control entirely by default. Passing user does not enable it — pass overrideAccess: false too.

const posts = await payload.find({
  collection: 'posts',
  where: { _status: { equals: 'published' } },
  overrideAccess: false,
  user: req.user,
})

Query _status, not status, once drafts are enabled. depth defaults to 2 and fans out relationship queries silently — see reference/queries.md.

Done when: every Local API call made on behalf of an end user passes overrideAccess: false with a user, and depth / select are set wherever payload size matters.

Access control

Read reference/access-control.md. The trap that breaks admin panels: during the Access Operation, id, data, doc, siblingData and blockData are all undefined, and a returned Where query is not executed. Guard every dereference.

Done when: each access function survives being called with no data and no id, and field-level rules return booleans only.

Hooks

Read reference/hooks.md. Two rules carry most failures: calling payload.update() on the document that triggered afterChange loops forever unless a context flag gates it, and a field hook must return the same type it received.

Done when: every hook that writes back is loop-guarded, and every hook running a nested operation forwards req.

Transactions

Apply thread the request: transactions run by default where the adapter supports them, and the failure mode is not propagating req. Pass req to every nested operation so it joins the same transaction.

The inverse trap: pass req only to promises you await. A detached promise holding req lets the request return OK for data that was rolled back.

SQLite has transactions off by default (transactionOptions: {} enables them); MongoDB needs a replica set.

Done when: every nested operation inside a hook or endpoint receives req, and every promise holding req is awaited.

Extending Payload

Read reference/extending.md for plugin authoring, custom endpoints, the jobs queue, storage adapters, and localization.

Done when: the plugin preserves the config it receives — spreading existing collections, fields, hooks, and plugins rather than replacing them.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.