Payload CMS - The Next-Gen TypeScript Headless CMS for Developers
Payload CMS is a self-hosted, TypeScript-based headless CMS designed for developers. Unlike traditional CMS platforms like WordPress or Drupal, Payload focuses on providing an API-first approach with complete flexibility, developer experience, and extensibility.
It’s built with Node.js, Express, and supports both MongoDB and PostgreSQL, offering a strong foundation for building modern web applications, SaaS products, and websites with custom backends.
Key Highlights
- TypeScript-first architecture
- Fully self-hosted and open-source
- Supports both MongoDB and PostgreSQL
- No front-end restrictions (headless)
- Custom APIs and GraphQL out of the box
- Local file storage or cloud integrations
- Admin panel auto-generated from schema
Why Developers Love Payload CMS
Payload is made by developers, for developers. It’s not just a CMS, it’s a framework that allows you to build exactly what you need.
- Full control over backend logic
- Strong TypeScript support
- First-class API with REST and GraphQL
- Customizable access control and authentication
- No plugin bloat
- Built-in file uploads and media management
Installation and Setup
Setting up Payload CMS is straightforward if you’re familiar with Node.js.
Prerequisites
- Node.js v18+
- MongoDB or PostgreSQL
Installation
# Create a new Payload project
npx create-payload-app my-payload-app
# Navigate into the directory
cd my-payload-app
# Install dependencies
npm install
# Run the project
npm run dev
Payload CMS runs locally at http://localhost:3000 by default, and the admin panel can be accessed via /admin.
Database Configuration
Payload CMS now supports PostgreSQL in addition to MongoDB. To switch to PostgreSQL, update your .env file:
DATABASE_URI=postgres://username:password@localhost:5432/payload_db
This enables developers who prefer relational databases and SQL to use Payload without depending on MongoDB.
Folder Structure Overview
A basic Payload project looks like this:
my-payload-app/
├── src/
│ ├── collections/
│ ├── globals/
│ ├── access/
│ ├── fields/
│ ├── hooks/
│ ├── endpoints/
│ └── payload.config.ts
├── package.json
├── tsconfig.json
└── .env
Each folder is modular and serves a specific purpose, collections define content types, access handles permissions, and hooks manage data lifecycle events.
Defining a Collection in Payload
Collections are similar to models in Mongoose or tables in SQL. They define how your content is structured.
Here’s an example of a Posts collection:
import { CollectionConfig } from "payload/types"
const Posts: CollectionConfig = {
slug: "posts",
admin: {
useAsTitle: "title",
},
fields: [
{
name: "title",
type: "text",
required: true,
},
{
name: "content",
type: "richText",
},
{
name: "author",
type: "relationship",
relationTo: "users",
},
{
name: "publishedDate",
type: "date",
},
],
}
export default Posts
Payload automatically generates an API and admin interface for this collection.
Access Control Example
Payload gives you complete control over who can do what.
import { Access } from "payload/types"
const isAdmin: Access = ({ req: { user } }) => {
return Boolean(user?.role === "admin")
}
const canReadPosts: Access = () => true
export default {
read: canReadPosts,
create: isAdmin,
update: isAdmin,
delete: isAdmin,
}
API Usage
Payload automatically exposes both REST and GraphQL endpoints.
REST Example
Fetch all posts:
GET /api/posts
Create a new post:
POST /api/posts
Content-Type: application/json
{
"title": "New Blog Post",
"content": "This is an example post."
}
GraphQL Example
query {
Posts {
docs {
title
content
}
}
}
Payload CMS vs Other Headless CMSs
| Feature | Payload CMS | Strapi | Sanity | Contentful |
|---|---|---|---|---|
| Hosting | Self-hosted | Self-hosted | Cloud | Cloud |
| Language | TypeScript | JavaScript | JavaScript | Proprietary |
| Database | MongoDB / PostgreSQL | SQLite, Postgres | Custom | Proprietary |
| Pricing | Free | Free | Paid tiers | Paid tiers |
| GraphQL | Built-in | Plugin | Built-in | Plugin |
| Admin Panel | Auto-generated | Auto-generated | Custom UI | Provided |
| Authentication | Built-in | Plugin-based | Plugin | Plugin |
Advantages of Payload CMS
- TypeScript-first: Ensures strong typing, autocompletion, and fewer runtime errors.
- Self-hosted: Full control over data and infrastructure.
- Flexible database support: Works with MongoDB or PostgreSQL.
- Flexible schema: You can define collections, relationships, and custom fields easily.
- Custom API routes: Build custom endpoints alongside the CMS.
- GraphQL and REST ready.
- File uploads and media management built-in.
- Rich access control for fine-grained security.
Disadvantages and Limitations
- Requires developer setup (not beginner-friendly).
- No built-in cloud hosting (you need your own server).
- Limited plugin ecosystem compared to Strapi or WordPress.
- Community still maturing, though expanding rapidly.
When to Use Payload CMS
Payload CMS is ideal if you:
- Want full control over your backend and data
- Prefer TypeScript and Node.js stack
- Are building custom web apps, SaaS products, or dashboards
- Need powerful access control logic
- Want self-hosting and data privacy
It’s not ideal if you:
- Need quick setup without coding
- Prefer a no-code or low-code CMS
- Don’t want to manage hosting and servers
Deploying Payload CMS
You can deploy Payload CMS on any Node.js-compatible server:
Example: Deploying to Vercel
- Set
DATABASE_URI(MongoDB or PostgreSQL) in environment variables. - Use Vercel’s Node.js build settings.
- Ensure you use a persistent database like MongoDB Atlas or Supabase.
Example: Deploying with Docker
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install
CMD ["npm", "run", "serve"]
Performance and Scalability
Payload CMS performs efficiently under high load thanks to:
- Express.js-based architecture
- PostgreSQL or MongoDB scalability
- Caching with Redis (optional)
- Optimized query handling
- Built-in API pagination and filtering
For scaling, you can use:
- Horizontal scaling via Docker/Kubernetes
- Load balancers for API routes
- CDNs for static media assets
Community and Ecosystem
The ecosystem is rapidly growing, with templates and integrations for frameworks like Next.js, Remix, and Astro.
Payload CMS is a powerful, developer-focused headless CMS built on modern technologies. With its new PostgreSQL support, TypeScript-first architecture, flexibility, and self-hosted model, it’s perfect for developers who value control, customization, and performance.
If you want a CMS that feels like part of your codebase, not a black box, Payload CMS is the right choice.