DEV Community

Alex Spinov
Alex Spinov

Posted on

Payload CMS Has a Free Headless CMS — Self-Host Your Content With TypeScript

The CMS Problem in 2026

Contentful charges per user. Sanity charges per dataset. Strapi needs a separate server. WordPress is... WordPress.

You want a CMS that is free, self-hosted, type-safe, and does not feel like it was built in 2010.

Payload: Code-First CMS That Lives in Your Next.js App

Payload is a headless CMS that runs inside your Next.js application. Not next to it. Inside it.

Free and Open Source

  • 100% open source (MIT license)
  • Self-hosted — no per-seat pricing, no API call limits
  • Runs in Next.js — one deployment, not two
  • PostgreSQL or MongoDB — your choice

Config as Code

// payload.config.ts
import { buildConfig } from 'payload'

export default buildConfig({
  collections: [
    {
      slug: 'posts',
      fields: [
        { name: 'title', type: 'text', required: true },
        { name: 'content', type: 'richText' },
        { name: 'author', type: 'relationship', relationTo: 'users' },
        { name: 'publishedAt', type: 'date' },
        { name: 'status', type: 'select', options: ['draft', 'published'] }
      ]
    }
  ]
})
Enter fullscreen mode Exit fullscreen mode

Your CMS schema is TypeScript. Version controlled. Code reviewed. Type-safe.

Auto-Generated Admin Panel

From that config, Payload generates:

  • A full admin panel with CRUD for every collection
  • Rich text editor with blocks
  • Media library with image optimization
  • User authentication and access control
  • REST and GraphQL APIs

Why Developers Choose Payload Over Strapi

Feature Payload Strapi
Language TypeScript JavaScript
Database Postgres/MongoDB Postgres/MySQL/SQLite
Next.js integration Native (same app) Separate server
Type safety Full Partial
Admin UI React (customizable) React
Access control Code-based (powerful) Role-based (simple)
License MIT MIT

The Killer Feature: Live Preview

// In your Next.js page
import { draftMode } from 'next/headers'
import { getPayload } from 'payload'

export default async function BlogPost({ params }) {
  const { isEnabled: isDraft } = await draftMode()
  const payload = await getPayload({ config })

  const post = await payload.findByID({
    collection: 'posts',
    id: params.id,
    draft: isDraft  // Show draft content in preview mode
  })

  return <article>{post.title}</article>
}
Enter fullscreen mode Exit fullscreen mode

Content editors see changes in real-time on the actual site. Not in a preview pane.

When to Use Payload

  • Next.js apps that need a CMS (blog, docs, marketing)
  • SaaS products with admin panels
  • E-commerce with custom product schemas
  • Any project where you want CMS without vendor lock-in

When to Use Something Else

  • Non-technical editors who need Notion-like simplicity (use Notion + API)
  • Static sites with minimal content (just use markdown)
  • Enterprise needing managed infrastructure (use Contentful)

Get Started

npx create-payload-app@latest
Enter fullscreen mode Exit fullscreen mode

Need content from external sources? 88+ web scrapers on Apify extract data from any website. Custom solutions: spinov001@gmail.com

Top comments (0)