TL;DR: Payload CMS is a free, open-source headless CMS you self-host. You define your content structure in TypeScript code, and Payload auto-generates a REST/GraphQL API, a fully functional admin dashboard, authentication, and file uploads. It's built on Next.js, which means your CMS and your website can live in the same project. No monthly SaaS bill. No vendor lock-in. Total control over your data.

Why AI Coders Need This

Every non-trivial web project needs a way to manage content. Blog posts. Product listings. Team member bios. Event pages. The question isn't whether you need a CMS — it's which one, and how much it'll cost you when your project grows.

The old options are annoying in familiar ways. Hosted SaaS CMS tools like Contentful and Sanity are fast to set up but charge per seat and per API call as you scale. WordPress is free but it's the wrong shape entirely for a modern Next.js app. Strapi is open-source and self-hosted but built on an older architecture that doesn't play nicely with TypeScript.

Payload CMS solves this differently. It's built by developers who were frustrated with all of the above. The result is a CMS that feels like a first-class TypeScript library rather than an external service you're bolting onto your stack.

When Chuck types "build me a blog with a CMS so clients can edit their own content," AI tools increasingly scaffold Payload. If you don't know what you're looking at, you'll be confused. This guide fixes that.

What Payload Actually Does

Payload CMS does several things at once, and understanding all of them is key to understanding why it's compelling.

It gives you a visual admin panel — for free

Every Payload project comes with a fully functional, customizable admin dashboard at /admin. No extra configuration. Your client can log in, create posts, upload images, and publish content without touching code. The admin UI is React-based and fully customizable if you need custom components, but it works perfectly out of the box.

It auto-generates an API

Every collection you define gets a REST API endpoint automatically. A Posts collection becomes GET /api/posts, POST /api/posts, GET /api/posts/:id, and so on. Payload also generates a full GraphQL schema. You define the data shape once in TypeScript and get both API flavors for free.

It handles auth out of the box

Payload has a built-in authentication system. Admin users, editor roles, contributor roles — all manageable through the admin panel or via API. You can lock down which content types each role can read, write, or delete. For most client projects, this is enough without any extra configuration.

It handles file uploads

Images, PDFs, video assets — Payload has a built-in media collection with upload handling, image resizing, alt text fields, and focal point selection. You can plug in cloud storage (S3, Cloudflare R2) with a single config option.

It's TypeScript from top to bottom

You define collections in TypeScript. Payload infers the types. Your front-end components get full type safety — the same type that describes your database schema is the same type you use in your React props. This is the killer feature for vibe coders: when AI generates your data-fetching code, it can be precisely correct because the types flow end to end.

How It Works: Collections, Fields, and the Admin Panel

Collections

The core concept in Payload is a collection. A collection is a group of documents that share the same structure — like a database table. You define collections in code:

// payload.config.ts
import { buildConfig } from 'payload'
import { postgresAdapter } from '@payloadcms/db-postgres'
import { lexicalEditor } from '@payloadcms/richtext-lexical'

export default buildConfig({
  // Your database — Payload supports PostgreSQL and MongoDB
  db: postgresAdapter({
    pool: { connectionString: process.env.DATABASE_URL },
  }),

  // Collections — each one becomes a section in the admin panel
  // and a set of REST API endpoints
  collections: [
    {
      slug: 'posts',          // becomes /api/posts
      admin: {
        useAsTitle: 'title',  // which field shows as the record name in admin
      },
      fields: [
        {
          name: 'title',
          type: 'text',
          required: true,
        },
        {
          name: 'content',
          type: 'richText',   // full rich text editor (Lexical by default)
          editor: lexicalEditor({}),
        },
        {
          name: 'publishedAt',
          type: 'date',
        },
        {
          name: 'author',
          type: 'relationship', // links to another collection
          relationTo: 'users',
        },
        {
          name: 'heroImage',
          type: 'upload',       // links to your media collection
          relationTo: 'media',
        },
      ],
    },
    {
      slug: 'media',
      upload: true,   // this flag makes Payload handle file uploads for this collection
      fields: [
        {
          name: 'alt',
          type: 'text',
        },
      ],
    },
  ],
})

That's it. Run Payload and you now have:

  • A /admin panel with a Posts section and a Media section
  • GET /api/posts — list all posts
  • GET /api/posts/:id — get a single post
  • POST /api/posts — create a post (authenticated)
  • PATCH /api/posts/:id — update a post
  • DELETE /api/posts/:id — delete a post
  • Full GraphQL schema at /api/graphql

Fields

Fields are the properties of each document in a collection. Payload has a rich set of field types:

Field Type What It Does
text Single line text input. Titles, slugs, names.
textarea Multi-line plain text. Excerpts, descriptions.
richText Full rich text editor (bold, links, headings, images, embeds).
number Numeric value. Prices, quantities, ratings.
select Dropdown of predefined options. Status fields, categories.
relationship References another collection. Author → User. Post → Category.
upload References the media collection. Hero images, attachments.
array Repeatable group of sub-fields. FAQs, team members, gallery items.
blocks Page builder-style field. Each block is a different layout component.
group Organizes related fields into a named group. SEO settings, social links.

Global Documents

Not everything in a CMS is a list. Some things are singular: the site header, the homepage hero text, SEO defaults. Payload has a concept called globals — single-document collections that don't paginate. Your clients edit them in the admin panel and they're exposed via API at /api/globals/site-settings.

Hooks

Payload has a hook system that lets you run custom code before or after operations. Before a post is created, validate a slug. After a post is published, send a webhook to Vercel to trigger a rebuild. This is where you can put real business logic without hacking around the CMS constraints. It's the feature that makes Payload suitable for serious projects, not just simple blogs.

Payload 3.0 and Next.js

Payload 3.0 (released late 2024) was a major architectural shift. Instead of running as a separate Node.js server, Payload became a Next.js plugin. Your Next.js app and your Payload CMS live in the same next.config.js, the same package.json, and the same deployment. The admin panel is served as Next.js routes. Your database queries run inside Next.js server components. One codebase, one deployment.

This is why AI tools reach for Payload when you're building on Next.js — the integration is seamless rather than bolt-on.

Payload vs Sanity vs Contentful vs Strapi

Each of these tools has a different philosophy. Here's how they actually compare for a vibe coder building real projects.

Feature Payload Sanity Contentful Strapi
Hosting Self-hosted Managed cloud Managed cloud Self-hosted
Open source Yes (MIT) Partial No Yes (MIT)
Free tier Pay infra only Limited (3 users) Limited (5 users) Pay infra only
TypeScript-first Yes — built in Codegen required Codegen required Partial support
Next.js integration Native plugin Good SDK Good SDK Separate service
Custom business logic Full hooks system Webhooks only Webhooks only Lifecycle hooks
Real-time collaboration Not built in Yes No No
Setup complexity Medium Low Low Medium
Vendor lock-in risk None High (proprietary DB) High None

Payload vs Sanity

Sanity is the most popular hosted headless CMS right now, and for good reason: setup is five minutes, the editing experience is exceptional, and real-time collaborative editing is genuinely excellent. But Sanity stores your data in Sanity's proprietary database (GROQ queries, not SQL). You can't easily export your content, run your own queries, or avoid the per-seat pricing as your team grows. Payload wins on ownership and flexibility. Sanity wins on editorial experience and zero infrastructure management.

Payload vs Contentful

Contentful is the enterprise standard — heavily used, reliable, with an excellent SDK. But it's expensive at scale (the free tier is genuinely limiting), it's fully closed source, and customization requires webhooks and external services. Payload does everything Contentful does but you pay for your own PostgreSQL database instead of Contentful's pricing tiers.

Payload vs Strapi

Strapi is the closest comparison — also open-source, also self-hosted, also generates an admin panel and API. But Strapi was built before TypeScript was dominant and it shows: the TypeScript support is bolted on rather than native. Strapi also has a GUI-first workflow (you define content types in the admin panel, not in code), which creates a content-types directory that doesn't play nicely with git. Payload is code-first — your schema lives in TypeScript files and is version-controlled alongside your app.

When AI Suggests Payload

AI tools reach for Payload in specific situations. Knowing these patterns helps you understand whether the suggestion fits your project.

You're building a Next.js app that needs a CMS

This is the most common trigger. When you're already in a Next.js project and ask for CMS functionality, Payload is the natural fit because of its native plugin architecture. The types flow directly from your Payload config into your React components without any codegen step.

You need users or roles in your app

Payload has a full auth system built in. When your project needs "admin users vs regular users" or "editors who can draft posts but not publish," AI often reaches for Payload rather than making you configure NextAuth.js separately.

The client needs to edit content

If you're building for someone else and they need a visual interface to update their own website content, Payload's admin panel is the selling point. It's polished, customizable, and requires no technical knowledge to use.

You need file uploads with image management

When the prompt mentions "image gallery," "product photos," or "avatar uploads," AI will often scaffold Payload's media collection because it handles resizing, focal points, and cloud storage integration in a few lines of config.

Self-hosting is a requirement

When you mention "no monthly fees," "GDPR," "data ownership," or "everything on my own server," AI understands this rules out managed SaaS CMS tools and will suggest Payload or Strapi as the self-hosted alternatives.

What AI Gets Wrong About Payload

Payload is well-represented in AI training data, but there are patterns where AI trips up. Watch for these.

1. Mixing up Payload 2 and Payload 3 syntax

Payload 3.0 was a complete rewrite with a different API surface. payload.config.ts structure, the database adapter imports, and the Next.js integration all changed significantly. AI trained on older data sometimes generates Payload 2.x code — which has a separate Express server, a different config format, and doesn't integrate into Next.js the same way. If the generated scaffold has an express import or a server.ts that manually starts Payload, that's Payload 2 syntax. Ask AI to update it to Payload 3 with the Next.js plugin.

2. Forgetting the database adapter

Payload 3 requires an explicit database adapter — either @payloadcms/db-postgres or @payloadcms/db-mongodb. AI sometimes generates a config that imports from payload but forgets to add the database adapter import and configuration. This causes a clear startup error, but it's confusing if you don't know what to look for. Check that your payload.config.ts has a db: field pointing to a database adapter.

3. Missing environment variables

Payload needs at minimum a DATABASE_URL (connection string to PostgreSQL or MongoDB) and a PAYLOAD_SECRET (a random string used to sign auth tokens). AI sometimes scaffolds the code correctly but doesn't tell you what environment variables to set. If Payload refuses to start with a cryptic error, check whether these two variables are set in your .env file.

4. Over-engineering the access control

Payload has a powerful access control system where each collection can define granular read/write permissions per role. For simple projects, AI sometimes generates a dense access control configuration that's correct but overwhelming. If you're just building a personal blog where you're the only editor, you don't need field-level access control. Start with simple collection-level rules and add granularity later.

5. Not configuring image resizing

Payload's media collection supports automatic image resizing — you define sizes in the collection config and Payload generates them on upload. AI sometimes scaffolds a media collection without any imageSizes configuration, which means you'll only have original-size images. For performance on the web, always define at least a thumbnail and a card size in your media collection. Ask AI to add image size definitions if they're missing.

Heads up: Payload 3 requires Node.js 20+ and a PostgreSQL or MongoDB database. If AI scaffolds a Payload project but doesn't ask you about your database, make sure you have one set up. Railway and Supabase both offer free PostgreSQL instances that work perfectly with Payload.

Real Scenario: AI Scaffolding a Payload Project

Prompt I Would Type

Build me a Next.js website for a local bakery. The bakery owner needs to be able to:
- Add and edit their menu items (name, description, price, photo, category)
- Write blog posts about seasonal specials
- Update their homepage hero text and opening hours

Use Payload CMS so the owner has a nice admin panel.
I'll host this on Railway with a PostgreSQL database.
Use TypeScript throughout.

What AI generates from this prompt:

  • A Next.js 15 project with Payload 3 installed as a plugin
  • A payload.config.ts with three collections: menu-items, posts, media
  • A globals section with a site-settings document for the hero text and opening hours
  • Full TypeScript types auto-generated for every collection
  • Admin panel at /admin with role-based auth
  • REST API endpoints for all collections
  • Next.js server components that fetch from Payload using the local API (faster than HTTP on the same server)
  • A .env.example file with the required variables

That's a genuinely complete CMS-backed website. The bakery owner gets a polished admin panel. You get a codebase you own, running on infrastructure you control, with no per-month SaaS bill from the CMS layer.

Frequently Asked Questions

Payload CMS is an open-source, TypeScript-first headless CMS built on Next.js. You define your content structure in code (called collections), and Payload automatically generates a REST and GraphQL API, a visual admin panel, authentication, file upload handling, and more. You self-host it — no monthly SaaS fees, no vendor lock-in.

Payload itself is free and open-source (MIT license). You pay for the infrastructure to host it — a database (PostgreSQL or MongoDB) and a server. On Railway or similar platforms, a small Payload project typically costs $5–$20/month total. There's no per-user fee or content-entry limit.

WordPress is a traditional CMS — it manages content and renders the front-end website in one coupled system. Payload is headless, meaning it only handles the content and API layer. Your front-end (a Next.js app, a React app, a mobile app) fetches content from Payload's API. Payload is also code-first and TypeScript-native, which makes it far better suited for modern application development.

Yes — Payload 3.0 was rebuilt as a Next.js plugin. Your Payload admin panel and your Next.js front-end live in the same project, share the same TypeScript types, and deploy as a single app. This means you get one codebase, one deployment, and full type-safety from your database schema all the way to your React components.

Choose Payload when you want self-hosting (no vendor lock-in), when you need custom business logic inside your CMS (like workflows, computed fields, or auth integrations), when your content model is complex, or when you're already building in Next.js and TypeScript. Choose Sanity or Contentful when you want a fully managed cloud service, a simpler setup, or real-time collaborative editing out of the box.

What to Learn Next