Payload CMS 3.0 – The Good, the Great, and the Challenges

Over the last few months, I’ve been using Payload CMS to build a complex healthcare application, and the recent version 3 release has been both exciting and challenging. Here are the top features and insights from my software team’s development journey.

Effortless Project Setup

Getting started with Payload CMS is incredibly straightforward. With just a few commands, you can generate a new project:

npx create-payload-app

The CLI offers multiple templates, allowing you to quickly bootstrap a project tailored to your needs. A few simple steps and you’re ready to start developing.

Seamless Next.js 15 Integration

Payload v3 ties in beautifully with Next.js 15 and React Server Components (RSC). This integration allows for:
– Easy creation of API and page routes outside the admin dashboard
– First-class support for server-side operations
– Ability to keep expensive queries and operations on the server

Powerful and Granular Access Control

The access control system allows for complex permission scenarios, which was crucial for our healthcare application:
– At the collection level
– At the field level
– Using flexible utility functions

This granularity allows for complex, nuanced user access management. The type system ensures robust and type-safe access control implementations.

// Access control utility functions
const medicalStaffOnly: Access = ({ req: { user } }) => {
return Boolean(user?.role === 'medical' || user?.role === 'admin')
}

const restrictSensitiveFields: Access = ({ req: { user } }) => {
return Boolean(
user?.role === 'medical' ||
user?.role === 'admin' ||
user?.role === 'nurse'
)
}

export const HealthRecords: CollectionConfig = {
access: {
create: medicalStaffOnly,
read: restrictSensitiveFields,
},
fields: [
{
name: 'diagnosis',
type: 'text',
access: {
read: restrictSensitiveFields,
update: medicalStaffOnly
}
}
]
...rest,
}

Custom Components and Admin UI

Payload makes it easy to extend and customize the admin UI. Here’s how we customized the save button to add confirmation for important changes:

export const HealthRecords: CollectionConfig = {
// ... rest of collection config
admin: {
components: {
// Custom save button with confirmation
SaveButton: ({ onClick }) => {
return (
<button> {
e.preventDefault()
if (window.confirm('Are you sure you want to save these changes?')) {
onClick(e)
}
}}
>
Save Changes
</button>
)
}
}
}
}

Hooks and Data Transformation

Payload’s hooks provide powerful data manipulation capabilities:

export const HealthRecords: CollectionConfig = {
// ... rest of collection config
hooks: {
beforeChange: [
({ data, operation }) => {
if (operation === 'create') {
data.createdAt = new Date()
}
data.lastModified = new Date()
return data
}
],
afterChange: [
({ doc, operation }) => {
// Log changes for audit purposes
logAuditEvent({
operation,
recordId: doc.id,
timestamp: new Date()
})
return doc
}
]
}
}

The plugin ecosystem adds significant flexibility with minimal configuration effort.

Bonus: Extensible Ecosystem

Payload’s plugin and adapter system makes it easy to:
– Set up databases
– Configure email services
– Implement file storage
– Customize admin dashboard components
– Override default styles

Challenges We Encountered

Our journey included some hurdles, particularly around complex relationships and deployment workflows. However, the framework’s robust features and active development make it a compelling choice for complex web applications. No framework is perfect.

Complex Relationships

Managing relationships between collections became particularly challenging, especially when dealing with conditional logic and nested relationships. In hindsight, we could have structured our data differently to avoid some of these complexities.

Deployment and Seeding Challenges

  • Difficulties running seed functions in Vercel Preview and Production environments
  • Inconsistent database initialization across deployment stages
  • Had to implement custom solutions for handling environment-specific seeding

Documentation Gaps

  • During the beta phase, documentation became quickly outdated
  • Lack of comprehensive guides for database migrations
  • Limited examples for complex relationship scenarios

Final Thoughts

Payload CMS 3.0 offers a powerful content management solution with remarkable flexibility.

The combination of granular access controls, custom component support, and strong TypeScript integration provided the foundation we needed for our healthcare application. As the ecosystem matures and documentation improves, we’re excited to see how Payload continues to evolve.

Conversation

Join the conversation

Your email address will not be published. Required fields are marked *