VOOZH about

URL: https://thenewstack.io/introduction-to-payload-a-headless-cms-and-app-framework/

⇱ Introduction to Payload, a Headless CMS and App Framework - The New Stack


TNS
SUBSCRIBE
Join our community of software engineering leaders and aspirational developers. Always stay in-the-know by getting the most important news and exclusive content delivered fresh to your inbox to learn more about at-scale software development.
REQUIRED
It seems that you've previously unsubscribed from our newsletter in the past. Click the button below to open the re-subscribe form in a new tab. When you're done, simply close that tab and continue with this form to complete your subscription.
The New Stack does not sell your information or share it with unaffiliated third parties. By continuing, you agree to our Terms of Use and Privacy Policy.
Welcome and thank you for joining The New Stack community!
Please answer a few simple questions to help us deliver the news and resources you are interested in.
REQUIRED
REQUIRED
REQUIRED
REQUIRED
REQUIRED
Great to meet you!
Tell us a bit about your job so we can cover the topics you find most relevant.
REQUIRED
REQUIRED
REQUIRED
REQUIRED
REQUIRED
Welcome!

We’re so glad you’re here. You can expect all the best TNS content to arrive Monday through Friday to keep you on top of the news and at the top of your game.

What’s next?

Check your inbox for a confirmation email where you can adjust your preferences and even join additional groups.

Follow TNS on your favorite social media networks.

Become a TNS follower on LinkedIn.

Check out the latest featured and trending stories while you wait for your first TNS newsletter.

PREV
1 of 2
NEXT
VOXPOP
As a JavaScript developer, what non-React tools do you use most often?
Angular
0%
Astro
0%
Svelte
0%
Vue.js
0%
Other
0%
I only use React
0%
I don't use JavaScript
0%
Thanks for your opinion! Subscribe below to get the final results, published exclusively in our TNS Update newsletter:
NEW! Try Stackie AI
From clobbered drafts to real-time sync
Apr 14th 2026 10:00am, by David Moore
TypeScript 6.0 RC arrives as a bridge to a faster future
Mar 14th 2026 9:00am, by Darryl K. Taft
Mastra empowers web devs to build AI agents in TypeScript
Jan 28th 2026 11:00am, by Loraine Lawson
2024-09-09 05:43:06
Introduction to Payload, a Headless CMS and App Framework
tutorial,
Developer tools / Frontend Development

Introduction to Payload, a Headless CMS and App Framework

We take a look at Payload, an intriguing CMS and app framework choice if you don’t need your frontend and backend to be tied together.
Sep 9th, 2024 5:43am by David Eastman
👁 Featued image for: Introduction to Payload, a Headless CMS and App Framework
Image via Unsplash+. 
One of the interesting things about web development has always been the attempt to merge the worlds of visual design with that of data design. While they need to come together in websites and web apps, they are quite separate disciplines. Frameworks like Ruby on Rails consistently jump back and forth over the fence in an effort to pull them together. Payload CMS bravely describes itself as a “headless CMS and application framework.” Although we don’t refer to user interfaces as “heads,” headless just refers to a framework with no exclusive frontend. A content management system (CMS) is just a framework that manipulates structured data. If the data is a blog, then the content being managed are posts, for example. The What is Payload page does a good job of presenting this dilemma, as well as trying to explain its own angle. It hits pay dirt when it recognises that a CMS tends to “bind the presentation of your content to the storage of your content.” Accordingly, what Payload aims to do is to work with whatever frontend you want to use. As of now, Payload is between some breaking changes and version 3, so old documentation may be out of date. Following the instructions as I did, I got an older version. This will no doubt be smoothed out. Just check its Discord channel for the latest information.

Installation

As yet, the installation pre-requisite options are a bit narrow for databases, but there is one relational and one document-based example to choose from: 👁 Image
On my trusty MacBook, I installed a community MongoDB via Homebrew: 👁 Image
👁 Image
Then I started Mongo up by adding it as a service: 👁 Image
We can see the connection string as the URL, so we should be able to set up Payload. In another browser tab, I installed the Payload app: 👁 Image
I set up a demo project and soon we are ready to launch: 👁 Image
One of the example projects failed because it expected Discord! As I’ve said, because of the upcoming changes some of the documentation and videos don’t quite match up yet. That’s a good thing of course — the project is very active. I selected the payload-demo template, which was fine. Then “yarn dev” runs the project: 👁 Image
After MongoDB is connected to, it starts up both the payload admin (at localhost:3000/admin) as well as the demonstration app (marked as Next.js app, the React framework used for the template).

The Payload App

Going straight into the app we see: 👁 Image
At this point, there is no content, so you are guided to the admin dashboard to start making some. The admin dashboard allows me to create an Admin role or User role, with email. The dashboard itself helps to explain what Payload is actually about: 👁 Image
Payload organizes everything into sets of types in collections. This include Pages and Users. We can create new types and start using them immediately, as we will do. There is a slight confusion here: To start things off, you press the link to “Seed the database,” and you will get lots of demo content. That will clean out anything that already exists. You also need to make a “home” page, otherwise you will just see the default template page from above, which will perhaps make you think you have no content, when you have. Once I understood the system, I created some simple if uninspired content on a Page type: 👁 Image
Once you use the admin interface to add to the collections, you can then Publish any changes (commit them). This will automatically update your site.

Doing Everything in Code

Now at this stage, I’ve not done much more than you could do with, say, Publii, which also acts like a classic CMS. However, there are two things that stand out in Payload. Not only can you talk to it in REST, you can reuse parts of Payload that blur the distinction between who owns what. And you can do everything in code, which is where we go now. For example, you can see that Users is a collection type, available for use by us: 👁 Image
And where are these registered? All in the `payload.config.ts` file. First they are imported, then (as you can see below) added into the known collections: 👁 Image
Within the Users folder, we have a basic index.ts file, which defines the Users type. While this includes quite a lot of Typescript, most of it is just describing the admin access. Payload allows quite a lot of granular access control:
import type { CollectionConfig } from 'payload/types' 
import { admins } from '../../access/admins' 
import { anyone } from '../../access/anyone' 
import adminsAndUser from './access/adminsAndUser' 
import { checkRole } from './checkRole' 
import { ensureFirstUserIsAdmin } from './hooks/ensureFirstUserIsAdmin' 
import { loginAfterCreate } from './hooks/loginAfterCreate' 

const Users: CollectionConfig = { 
 slug: 'users', 
 admin: { 
 useAsTitle: 'name', 
 defaultColumns: ['name', 'email'], 
 }, 
 access: { 
 read: adminsAndUser, 
 create: anyone, 
 update: adminsAndUser, 
 delete: admins, 
 admin: ({ req: { user } }) => checkRole(['admin'], user), 
 }, 
 hooks: { 
 afterChange: [loginAfterCreate], 
 }, 
 auth: true, 
 fields: [ 
 { 
 name: 'name', 
 type: 'text', 
 }, 
 { 
 name: 'roles', 
 type: 'select', 
 hasMany: true, 
 defaultValue: ['user'], 
 options: [ 
 { 
 label: 'admin', 
 value: 'admin', 
 }, 
 { 
 label: 'user', 
 value: 'user', 
 }, 
 ], 
 hooks: { 
 beforeChange: [ensureFirstUserIsAdmin], 
 }, 
 access: { 
 read: admins, 
 create: admins, 
 update: admins, 
 }, 
 }, 
 ], 
 timestamps: true, 
} 

export default Users
However, we are going to pare this down and create our own collection type, with no admin or hooks. Let’s say we just want a type called Members. I’ll make the appropriate folder and create a hacked down index.ts:
import type { CollectionConfig } from 'payload/types' 

const Members: CollectionConfig = { 
 slug: 'members', 
 fields: [ 
 { 
 name: 'name', 
 type: 'text', 
 }, 
 { 
 name: 'membership', 
 type: 'number', 
 }, 
 ], 
 timestamps: true, 
} 

export default Members
This just describes a type with a name and numeric membership field. Payload does a lot of work through the different fields. The server detected the changes: 👁 Image
And immediately the collections recognised the new type within the admin panel: 👁 Image
And we can manipulate members like any other collection type: 👁 Image
One last thing. Let’s access our new member via REST: 👁 Image
So we are locked out. But wait a minute … remember the granular access we removed to make the Member collection simple? Let’s try to put a bit back in:
import type { CollectionConfig } from 'payload/types'
import { anyone } from '../../access/anyone'

const Members: CollectionConfig = {
 slug: 'members',
 access: {
 read: anyone,
 },
 fields: [
 {
 name: 'name',
 type: 'text',
 },
 {
 name: 'memebership',
 type: 'number',
 },
 ],
 timestamps: true,
}

export default Members
All I did was add the import for “anyone” and add that access. Now let’s try: 👁 Image
Pretty good. We created a new collection, saw it in the admin console, created an entry for it and even requested it via REST. So this content is now available for my site.

Conclusion

As I said earlier, Payload is currently transitioning to version 3, so it may make sense to hold out for a bit before investigating it. That said, the idea is already quite a strong one if you don’t insist that your frontend and backend endure a shotgun wedding.
TRENDING STORIES
David has been a London-based professional software developer with Oracle Corp. and British Telecom, and a consultant helping teams work in a more agile fashion. He wrote a book on UI design and has been writing technical articles ever since....
Read more from David Eastman
SHARE THIS STORY
TRENDING STORIES
SHARE THIS STORY
TRENDING STORIES
TNS DAILY NEWSLETTER Receive a free roundup of the most recent TNS articles in your inbox each day.
The New Stack does not sell your information or share it with unaffiliated third parties. By continuing, you agree to our Terms of Use and Privacy Policy.