Skip to main content Home Creators asymmetric-al core payload
payload Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks, access control, Payload API). Use when debugging validation errors, security issues, relationship queries, transactions, or hook behavior.
Jump to install Skills Marketplace Discover and explore AI skills built by the community.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Copy promptShow prompt details A direct command skips the review prompt. Inspect the source before running it.
npx skills add https://github.com/Asymmetric-al/core --skill payloadThe command stays on one line. Scroll horizontally to inspect it before copying.
Prefer a local copy? Download the files currently available to SkillsMP.
Download Zip Downloading... More from this repository Pointer to the canonical agent instruction and skill system for this monorepo
Tasteful, subtle web UI animation following Emil Kowalski / animations.dev principles. Use when adding or reviewing interface motion — hover and press feedback, entrances and exits, modals, toasts, menus, loading and skeleton states, staggered reveals, page or view transitions — so motion stays refined and purposeful, not decorative. Covers CSS, Web Animations, and React timing/easing. Pair with the motion skill for motion/react API specifics.
Build correct cached/dynamic boundaries in the Next.js App Router when Cache Components or PPR are enabled. Use when working with cacheComponents, Partial Prerendering (PPR), 'use cache', cacheLife, cacheTag, updateTag, or revalidateTag, to avoid request-context leaks and enforce proper cache invalidation. Not for the Pages Router or when Cache Components/PPR are off.
Related occupations SOC
Based on SOC occupation classification
name payload description Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks, access control, Payload API). Use when debugging validation errors, security issues, relationship queries, transactions, or hook behavior.
Payload CMS Application Development
Payload is a Next.js native CMS with TypeScript-first architecture, providing admin panel, database management, REST/GraphQL APIs, authentication, and file storage.
Quick Reference
Quick Start npx create-payload-app@latest my-app
cd my-app
pnpm dev
Minimal Config import { buildConfig } from 'payload'
import { mongooseAdapter } from '@payloadcms/db-mongodb'
import { lexicalEditor } from '@payloadcms/richtext-lexical'
import path from 'path'
import { fileURLToPath } from 'url'
const filename = fileURLToPath (import .meta .url )
const dirname = path.dirname (filename)
export default buildConfig ({
admin : {
user : 'users' ,
importMap : {
baseDir : path.resolve (dirname),
},
},
collections : [Users , Media ],
editor : lexicalEditor (),
secret : process.env .PAYLOAD_SECRET ,
typescript : {
outputFile : path.resolve (dirname, 'payload-types.ts' ),
},
db : mongooseAdapter ({
url : process.env .DATABASE_URL ,
}),
})
Essential Patterns
Basic Collection import type { CollectionConfig } from 'payload'
export const Posts : CollectionConfig = {
slug : 'posts' ,
admin : {
useAsTitle : 'title' ,
defaultColumns : ['title' , 'author' , 'status' , 'createdAt' ],
},
fields : [
{ name : 'title' , type : 'text' , required : true },
{ name : 'slug' , type : 'text' , unique : true , index : true },
{ name : 'content' , type : 'richText' },
{ name : 'author' , type : 'relationship' , relationTo : 'users' },
],
timestamps : true ,
}
For more collection patterns (auth, upload, drafts, live preview), see COLLECTIONS.md .
Common Fields
{ name : 'title' , type : 'text' , required : true }
{ name : 'author' , type : 'relationship' , relationTo : 'users' , required : true }
{ name : 'content' , type : 'richText' , required : true }
{ name : 'status' , type : 'select' , options : ['draft' , 'published' ], defaultValue : 'draft' }
{ name : 'image' , type : 'upload' , relationTo : 'media' }
For all field types (array, blocks, point, join, virtual, conditional, etc.), see FIELDS.md .
Hook Example export const Posts : CollectionConfig = {
slug : 'posts' ,
hooks : {
beforeChange : [
async ({ data, operation }) => {
if (operation === 'create' ) {
data.slug = slugify (data.title )
}
return data
},
],
},
fields : [{ name : 'title' , type : 'text' }],
}
Access Control with Type Safety import type { Access } from 'payload'
import type { User } from '@/payload-types'
export const adminOnly : Access = ({ req } ) => {
const user = req.user as User
return user?.roles ?.includes ('admin' ) || false
}
export const ownPostsOnly : Access = ({ req } ) => {
const user = req.user as User
if (!user) return false
if (user.roles ?.includes ('admin' )) return true
return {
author : { equals : user.id },
}
}
Query Example
const posts = await payload.find ({
collection : 'posts' ,
where : {
status : { equals : 'published' },
'author.name' : { contains : 'john' },
},
depth : 2 ,
limit : 10 ,
sort : '-createdAt' ,
})
const post = await payload.findByID ({
collection : 'posts' ,
id : '123' ,
depth : 2 ,
})
const post = await payload.findByID ({
collection : 'posts' ,
id : '123' ,
depth : 0 ,
})
For all query operators and REST/GraphQL examples, see QUERIES.md .
Getting Payload Instance
import { getPayload } from 'payload'
import config from '@payload-config'
export async function GET ( ) {
const payload = await getPayload ({ config })
const posts = await payload.find ({
collection : 'posts' ,
})
return Response .json (posts)
}
import { getPayload } from 'payload'
import config from '@payload-config'
export default async function Page ( ) {
const payload = await getPayload ({ config })
const { docs } = await payload.find ({ collection : 'posts' })
return <div > {docs.map(post => <h1 key ={post.id} > {post.title}</h1 > )}</div >
}
Security Pitfalls
1. Local API Access Control (CRITICAL) By default, Local API operations bypass ALL access control , even when passing a user.
await payload.find ({
collection : 'posts' ,
user : someUser,
})
await payload.find ({
collection : 'posts' ,
user : someUser,
overrideAccess : false ,
})
overrideAccess: true (default) - Server-side operations you trust (cron jobs, system tasks)
overrideAccess: false - When operating on behalf of a user (API routes, webhooks)
2. Transaction Failures in Hooks Nested operations in hooks without req break transaction atomicity.
hooks : {
afterChange : [
async ({ doc, req }) => {
await req.payload .create ({
collection : 'audit-log' ,
data : { docId : doc.id },
})
},
]
}
hooks : {
afterChange : [
async ({ doc, req }) => {
await req.payload .create ({
collection : 'audit-log' ,
data : { docId : doc.id },
req,
})
},
]
}
3. Infinite Hook Loops Hooks triggering operations that trigger the same hooks create infinite loops.
hooks : {
afterChange : [
async ({ doc, req }) => {
await req.payload .update ({
collection : 'posts' ,
id : doc.id ,
data : { views : doc.views + 1 },
req,
})
},
]
}
hooks : {
afterChange : [
async ({ doc, req, context }) => {
if (context.skipHooks ) return
await req.payload .update ({
collection : 'posts' ,
id : doc.id ,
data : { views : doc.views + 1 },
context : { skipHooks : true },
req,
})
},
]
}
Project Structure src/
├── app/
│ ├── (frontend)/
│ │ └── page.tsx
│ └── (payload)/
│ └── admin/[[...segments]]/page.tsx
├── collections/
│ ├── Posts.ts
│ ├── Media.ts
│ └── Users.ts
├── globals/
│ └── Header.ts
├── components/
│ └── CustomField.tsx
├── hooks/
│ └── slugify.ts
└── payload.config.ts
Type Generation
export default buildConfig ({
typescript : {
outputFile : path.resolve (dirname, 'payload-types.ts' ),
},
})
import type { Post , User } from '@/payload-types'
Reference Documentation
FIELDS.md - All field types, validation, admin options
FIELD-TYPE-GUARDS.md - Type guards for runtime field type checking and narrowing
COLLECTIONS.md - Collection configs, auth, upload, drafts, live preview
HOOKS.md - Collection hooks, field hooks, context patterns
ACCESS-CONTROL.md - Collection, field, global access control, RBAC, multi-tenant
ACCESS-CONTROL-ADVANCED.md - Context-aware, time-based, subscription-based access, factory functions, templates
QUERIES.md - Query operators, Local/REST/GraphQL APIs
ENDPOINTS.md - Custom API endpoints: authentication, helpers, request/response patterns
ADAPTERS.md - Database, storage, email adapters, transactions
ADVANCED.md - Authentication, jobs, endpoints, components, plugins, localization
PLUGIN-DEVELOPMENT.md - Plugin architecture, monorepo structure, patterns, best practices
Resources