Contentful costs $300/month for a small team. Sanity charges per API call. Strapi's free tier works until you need custom fields — then you're rewriting plugins.
What if your CMS was code-first, fully typed, self-hosted, and free forever?
That's Payload CMS — a headless CMS that lives in YOUR codebase, not on someone else's server.
What Payload Gives You
- TypeScript-native — collections defined in code, fully typed API
- Self-hosted — runs on your server, your database, your rules
- Admin panel — auto-generated from your collection config
- REST + GraphQL API — auto-generated endpoints
- Authentication — built-in user management, access control, 2FA
- File uploads — media library with image resizing
- Versions & drafts — content versioning out of the box
- Localization — multi-language content with fallbacks
- Free forever — MIT licensed, no usage limits
Quick Start
npx create-payload-app@latest
cd my-cms && npm run dev
Define Collections in Code
// collections/Posts.ts
import type { CollectionConfig } from "payload";
export const Posts: CollectionConfig = {
slug: "posts",
admin: {
useAsTitle: "title",
},
access: {
read: () => true, // Public
create: ({ req }) => !!req.user, // Authenticated only
update: ({ req }) => req.user?.role === "admin",
delete: ({ req }) => req.user?.role === "admin",
},
fields: [
{ name: "title", type: "text", required: true },
{ name: "slug", type: "text", unique: true, required: true },
{
name: "content",
type: "richText",
// Lexical editor with custom blocks
},
{
name: "author",
type: "relationship",
relationTo: "users",
required: true
},
{
name: "category",
type: "select",
options: ["technology", "business", "design", "culture"],
},
{
name: "featuredImage",
type: "upload",
relationTo: "media"
},
{ name: "publishedDate", type: "date" },
{ name: "status", type: "select", options: ["draft", "published"], defaultValue: "draft" },
],
};
This generates:
- Admin UI with form fields, validation, and preview
- REST endpoints:
GET /api/posts,POST /api/posts, etc. - GraphQL schema with queries and mutations
- TypeScript types for the entire collection
Auto-Generated API
# REST — auto-generated from collections
GET /api/posts?where[status][equals]=published&limit=10&sort=-publishedDate
POST /api/posts
PATCH /api/posts/:id
DELETE /api/posts/:id
# GraphQL — also auto-generated
POST /api/graphql
// Type-safe local API (for Next.js, server functions, etc.)
const posts = await payload.find({
collection: "posts",
where: { status: { equals: "published" } },
limit: 10,
sort: "-publishedDate",
});
// posts is fully typed based on your collection config
Payload + Next.js Integration
Payload 3.0 embeds directly into Next.js:
// payload.config.ts
import { buildConfig } from "payload";
import { mongooseAdapter } from "@payloadcms/db-mongodb";
import { lexicalEditor } from "@payloadcms/richtext-lexical";
export default buildConfig({
admin: { user: "users" },
editor: lexicalEditor(),
db: mongooseAdapter({ url: process.env.DATABASE_URI }),
collections: [Posts, Users, Media],
});
Your CMS admin panel and your Next.js app run in the same process. No API latency for server-side rendering.
When to Choose Payload
Choose Payload when:
- You want CMS data in your codebase, not a third-party dashboard
- TypeScript-first development is non-negotiable
- You need fine-grained access control (RBAC, field-level permissions)
- Self-hosting is preferred (compliance, data sovereignty)
Skip Payload when:
- Non-technical editors need to manage content alone (Contentful/Sanity have better editor UX)
- You want zero infrastructure management (SaaS CMS is simpler)
- You need a CMS for a static site (Decap CMS or Tina CMS is lighter)
The Bottom Line
Payload CMS proves that "code-first" and "editor-friendly" aren't opposites. Developers define the schema in TypeScript; editors get an auto-generated admin panel that just works.
Start here: payloadcms.com
Need custom data extraction, scraping, or automation? I build tools that collect and process data at scale — 78 actors on Apify Store and 265+ open-source repos. Email me: Spinov001@gmail.com | My Apify Actors
Top comments (0)