BuildWithMatija
  1. Home
  2. Blog
  3. Payload
  4. Payload CMS 4.0: Latest Status and What’s Coming

Payload CMS 4.0: Latest Status and What’s Coming

Deep dive into Payload CMS 4.0: v4 migration guide, canary releases, breaking API changes, versions defaults, and…

27th May 2026·Updated on:5th October 2026·MŽMatija Žiberna·
Payload

Evaluating Payload CMS Implementation Costs?

Scope design, content structure, and migration hours to estimate a realistic production timeline and hosting setup.

Try the Cost EstimatorGet a Second Opinion

📚 Comprehensive Payload CMS Guides

Detailed Payload guides with field configuration examples, custom components, and workflow optimization tips to speed up your CMS development process.

No spam. Unsubscribe anytime.

Related Posts:

  • •Payload DAM: What Exists Today and What's Coming 4.0
  • •Payload CMS and Structured Autonomy: Fix Your Website Model
  • •Next.js & Payload CMS Multi-Tenant Architecture: Complete Production Guide
  • •Payload CMS for Publishing Teams: Honest Review — 2026
  • •How to Build E‑commerce with Payload CMS: Collections, Products, Variants
📄View markdown version
20

Comments

About the author

Matija Žiberna

Matija Žiberna

Full-stack developer, co-founder

AboutResume

Self-taught full-stack developer sharing lessons from building software and startups.

I'm Matija Žiberna, a self-taught full-stack developer and co-founder passionate about building products, writing clean code, and figuring out how to turn ideas into businesses. I write about web development with Next.js, lessons from entrepreneurship, and the journey of learning by doing. My goal is to provide value through code—whether it's through tools, content, or real-world software.

You might be interested in

Payload DAM: What Exists Today and What's Coming 4.0
Payload DAM: What Exists Today and What's Coming 4.0

12th July 2026

Payload CMS and Structured Autonomy: Fix Your Website Model
Payload CMS and Structured Autonomy: Fix Your Website Model

15th August 2026

Next.js & Payload CMS Multi-Tenant Architecture: Complete Production Guide
Next.js & Payload CMS Multi-Tenant Architecture: Complete Production Guide

12th December 2025

Payload CMS for Publishing Teams: Honest Review — 2026
Payload CMS for Publishing Teams: Honest Review — 2026

22nd March 2026

How to Build E‑commerce with Payload CMS: Collections, Products, Variants
How to Build E‑commerce with Payload CMS: Collections, Products, Variants

10th August 2025

Contents

  • At a glance (v4 canary & migration tracker)
  • 1. Breaking API changes and security defaults
  • `overrideAccess: false` by default in Local API
  • Default relationship depth drops from 2 to 1
  • Request creation API cleanup
  • Truthful configuration types (removal of `DeepRequired`)
  • Synchronous sanitization
  • 2. Database architecture and versioning by default
  • `versions: true` by default across collections and globals
  • `readVersions` permission inheritance
  • Database adapter type exports
  • 3. Auth, security, and request typing
  • Unified user types and typed `req.user`
  • Versioned JWT tokens (`authVersion`)
  • 4. Admin UI, semantic tokens, and Tailwind compatibility
  • Component configuration alignment for Globals
  • Elimination of Sass in favor of semantic CSS tokens
  • Tailwind CSS reset isolation
  • Native hierarchies, folders, and tags
  • 5. Lexical modernization and the removal of Slate
  • `@payloadcms/richtext-slate` is completely removed
  • Lexical 0.50 upgrade and table stabilization
  • 6. List view performance and the Select API
  • List View Select API enabled by default
  • `forceSelect` replaced by configurable `select()`
  • 7. Developer tooling, schemas, and the official codemod
  • The official migration codemod (`npx @payloadcms/codemod`)
  • Redesigned custom CLI commands (`config.cli.commands`)
  • `typescriptSchema` becomes `jsonSchema`
  • 8. MCP (Model Context Protocol) and AI agent workflows
  • 9. Framework ecosystem and TanStack Start
  • `@payloadcms/tanstack-start` canary
  • Minimum runtime baselines
  • The Big 4: Critical checklist for existing codebases
  • Recommended upgrade path
On this page:
  • At a glance (v4 canary & migration tracker)
  • 1. Breaking API changes and security defaults
  • 2. Database architecture and versioning by default
  • 3. Auth, security, and request typing
  • 4. Admin UI, semantic tokens, and Tailwind compatibility
Build with Matija logo

Build with Matija

Senior-led B2B websites, applications, content systems, and digital infrastructure. Business-first, full-stack, AI-assisted, no handoffs.

Services

  • B2B Website Development
  • CMS Architecture Review & Platform Blueprint
  • Next.js + Payload Advisory
  • AI Integration & Implementation

Resources

  • CMS Hub
  • B2B Website Strategy
  • E-commerce Hub
  • Blog
  • Case Studies
  • About Matija

Payload CMS

  • Payload CMS Developer
  • Payload CMS Migration
  • Payload CMS Demos
  • All Payload CMS Resources

Discuss your project

Planning a rebuild, migration, application, workflow change, or platform decision? Start with the business problem and the system behind it.

Book a discovery callContact me →
© 2026Build with Matija•All rights reserved•Privacy Policy•Terms of Service
BuildWithMatija
Get In Touch

Tip

Product manager, designer, or business owner? This guide is written for developers. For what Payload 4 means for your budget, team and risk, read Payload 4 for business owners.

Payload CMS 4.0 is no longer just an early roadmap preview or an experimental branch.

With active canary releases publishing across the entire ecosystem—including payload, @payloadcms/ui, database adapters, and @payloadcms/tanstack-start—and a comprehensive official 3.0 to 4.0 migration guide now merged into Payload's main branch, the shape of Payload 4 is concrete.

Payload 4 is not a mere version bump. It introduces fundamental behavioral shifts in access control security, database versioning defaults, TypeScript typing, and framework decoupling.

Note

This guide is continuously maintained against the official Payload v4 migration guide, canary releases, and active RFCs. It reflects the architecture being finalized for the stable release.

At a glance (v4 canary & migration tracker)

  • Current release train: v4.0.0-canary.37 (active cross-package canary ecosystem)
  • Latest stable 3.x release: Payload v3.90.2 (maintenance and hardening branch)
  • Official migration guide: Payload 3.0 to 4.0 Migration Guide (GitHub main)
  • Automated codemod: Available via npx @payloadcms/codemod
  • Minimum runtime baselines: Node.js 24.15.0+, Next.js 16.2.6+, TypeScript 6.0.3+
  • Production recommendation: Run Payload 3.x for current client deployments, but audit schemas, Local API queries, and auth types against the breaking changes outlined below.

Below is the definitive technical breakdown of what is changing in Payload 4.0, categorized into nine core architectural pillars, followed by the four highest-priority checks for production teams.


1. Breaking API changes and security defaults

The most consequential changes in Payload 4 involve subtle shifts in default behavior that directly affect application security and query performance.

overrideAccess: false by default in Local API

In Payload 3, invoking Local API methods (payload.find, payload.findByID, payload.create, etc.) without specifying overrideAccess effectively defaulted to bypassing access control. Local code executed with implicit superadmin privileges unless you explicitly passed overrideAccess: false alongside a user object.

In Payload 4, overrideAccess defaults to false:

typescript
// Payload 3 behavior:
// Executed as superadmin, ignoring collection access rules
const results = await payload.find({
  collection: 'orders',
});

// Payload 4 behavior:
// Enforces access control! If no user is present in req,
// this query runs as unauthenticated / public access.
const results = await payload.find({
  collection: 'orders',
  overrideAccess: true, // Required if you intend to bypass access control
});

The same Local API call follows different defaults depending on the Payload version:

Diagram

Without a user, access rules evaluate a public request. Use an explicit bypass only for trusted server-side work such as seeds and migrations.

This is a massive security hardening step. It prevents accidental data exposure in custom Next.js server actions, Route Handlers, and API endpoints where developers forgot to enforce user access. However, it will break existing cron jobs, migrations, seed scripts, and internal APIs that omitted overrideAccess: true.

Default relationship depth drops from 2 to 1

In Payload 3, relationship fields populated related documents up to a depth of 2 by default. While convenient for rapid prototyping, this frequently caused catastrophic query cascades on nested schemas, dragging database response times down on high-traffic sites.

In Payload 4, the default query depth is reduced from 2 to 1:

typescript
// Payload 3: populated post -> author -> author's avatar
// Payload 4: populates post -> author (author's avatar remains an ID string)
const post = await payload.findByID({
  collection: 'posts',
  id: '123',
});

// To restore deeper nesting on a specific query:
const postWithDeepRelations = await payload.findByID({
  collection: 'posts',
  id: '123',
  depth: 2,
});

One fewer populated level changes the response shape as well as the amount of database work:

Diagram

Solid arrows show populated relationships; the dashed arrow shows an ID reference. IDs may be strings or numbers depending on the adapter and ID configuration. Set depth: 2 on queries that need the avatar document.

You can restore the global default across your entire application in payload.config.ts:

typescript
export default buildConfig({
  defaultDepth: 2, // Restores Payload 3 global depth behavior
  // ...
});

Request creation API cleanup

The utility functions used to construct mock or synthetic Payload requests in custom endpoints and background workers have been standardized:

  • createLocalReq is removed and replaced by createPayloadRequest.
  • The old web-request-oriented createPayloadRequest is renamed to createPayloadRequestFromWebRequest.

Truthful configuration types (removal of DeepRequired)

In Payload 3, internal sanitized types like SanitizedConfig and SanitizedCollectionConfig wrapped properties in DeepRequired. This created a false sense of security in TypeScript, masking fields that were actually undefined at runtime.

Payload 4 removes DeepRequired from sanitized config types. If your plugins or custom admin components inspect config or collection settings, TypeScript may now flag properties that require explicit optional chaining (config.admin?.user).

Synchronous sanitization

Config sanitization and rich-text schema sanitization routines that previously returned Promises in multiple lifecycle stages have been refactored into synchronous functions, reducing asynchronous overhead during application bootstrap.


2. Database architecture and versioning by default

Payload 4 makes a fundamental shift in how document history and database schemas are handled.

versions: true by default across collections and globals

In Payload 3, collections and globals did not maintain document versions unless you explicitly configured versions: { drafts: true } or versions: true.

In Payload 4, versioning is enabled by default for all collections and globals, while drafts remain disabled by default.

Warning

If you upgrade an existing project without modifying your config, Payload 4 will generate migration scripts to create _versions database tables for every single collection and global in your schema!

If you operate a high-volume database or prefer lean, unversioned tables, you must explicitly opt out:

typescript
export const Invoices: CollectionConfig = {
  slug: 'invoices',
  versions: false, // Explicitly disable versions to prevent _invoices_versions table creation
  fields: [/* ... */],
};

For a relational adapter, the versioning decision determines which tables a migration must create:

Diagram

This shows the main and version-history tables, not every auxiliary table. MongoDB uses collections instead. Review generated migrations before applying them; the built-in Users collection explicitly disables versions.

The official codemod (npx @payloadcms/codemod) includes an automated transform to inject versions: false across all collections that were unversioned in Payload 3, ensuring existing databases do not experience unexpected table bloat. For teams managing production PostgreSQL instances, read our guide on why you should stop running Payload CMS in push mode and switch to migration-only workflows.

readVersions permission inheritance

Previously, if a collection enabled versions without defining a specific readVersions access control function, version queries defaulted to requiring full authentication.

In Payload 4, if readVersions is undefined, it inherits the collection's standard read access rule. If a collection has public read access, its published historical versions share that read access unless explicitly restricted with a dedicated readVersions rule.

Database adapter type exports

Import paths for database adapters have been flattened. Subpath imports like @payloadcms/db-postgres/types and @payloadcms/db-mongodb/types have been eliminated. All types and utilities now export directly from the package root:

typescript
// Payload 3:
import type { DrizzleConfig } from '@payloadcms/db-postgres/types';

// Payload 4:
import type { DrizzleConfig } from '@payloadcms/db-postgres';

3. Auth, security, and request typing

Authentication in Payload 4 undergoes both architectural hardening and a major TypeScript overhaul.

Unified user types and typed req.user

In Payload 3, user typing was fragmented across TypedUser, UntypedUser, and ClientUser. Access control functions and custom hooks frequently forced developers to cast req.user as User to avoid lint and compiler errors.

Payload 4 consolidates these types into two primary constructs:

  • User: The generic representation of a user document in your system.
  • AuthenticatedUser: The strongly-typed user attached to an authenticated request.

Via PR #17151, req.user is now properly typed as AuthenticatedUser throughout all hooks, endpoints, and access control callbacks. Crucially, req.user now natively includes runtime authentication metadata:

typescript
// Access control function in Payload 4:
export const canEditTenant: Access = ({ req }) => {
  if (!req.user) return false;

  // Strongly typed runtime auth properties:
  const strategy = req.user._strategy; // e.g., 'jwt', 'api-key'
  const sessionId = req.user._sid;     // Active session identifier

  return req.user.role === 'admin';
};

This eliminates the need for manual type assertions in multi-tenant authorization hooks and audit logging workflows. For real-world implementation patterns, see our guide on building a production-ready multi-tenant architecture with Next.js and Payload.

Versioned JWT tokens (authVersion)

JWT tokens issued by Payload 4 now include an authVersion field embedded directly within the protected JWT header. The payload shape remains flat and performant, but the header versioning ensures that:

  1. Stale tokens generated under incompatible Payload 3 auth strategies can be safely rejected rather than throwing cryptic runtime deserialization errors.
  2. In-flight token rotations and strategy migrations can be performed without session corruption.

4. Admin UI, semantic tokens, and Tailwind compatibility

Payload's admin panel receives its most substantial design refresh since the 3.0 launch, focusing on visual density, custom branding, and modern frontend styling interoperability.

Diagram

The sidebar organizes content; drawers keep related editing in context. CSS tokens control the presentation, while reset isolation supports custom Tailwind views.

Component configuration alignment for Globals

In Payload 3, configuring custom admin components for globals used a different property structure than collections (admin.components.elements vs admin.components.edit).

Payload 4 unifies globals with collections:

  • globalConfig.admin.components.elements is renamed to globalConfig.admin.components.edit.
  • Globals gain full parity with collections for defining custom views, tabs, and action bars.

Elimination of Sass in favor of semantic CSS tokens

The legacy Sass (scss) build pipeline has been completely removed from @payloadcms/ui. All admin styling now relies on pure CSS and semantic design tokens configured via CSS variables.

This provides two major wins:

  1. Effortless admin theming: Agencies and platform builders can rebrand the Payload admin interface by overriding standard tokens (brand colors, neutral scales, surface radiuses, borders) without compiling Sass assets or overriding deeply nested CSS classes.
  2. Faster build times: Removing Sass eliminates heavy preprocessing steps during local development and containerized deployments.

Tailwind CSS reset isolation

In Payload 3, using Tailwind CSS or component libraries like shadcn/ui inside custom admin views was prone to style pollution: the admin panel's base styles bled into Tailwind elements, while Tailwind's Preflight reset broke default Payload field styling.

Payload 4 adopts an isolated CSS reset strategy. Custom admin views, custom fields, and dashboard widgets can now use modern Tailwind classes without conflict, making it seamless to construct bespoke client experiences.

Native hierarchies, folders, and tags

Payload 4 brings hierarchical content organization into core:

  • Folders: Single-parent containment for grouping pages, documents, and media assets.
  • Tags: Multi-dimensional categorization across collections.
  • Sidebar tabs: The admin sidebar supports expandable tabs and custom navigational panels, allowing editors to browse documents via content trees rather than flat, paginated tables.

This reduces the need for community plugins like nested-docs and aligns with how enterprise editorial teams organize large publishing corpuses. For an assessment of editor workflows, see our Payload CMS for publishing teams review.


5. Lexical modernization and the removal of Slate

Rich text editing in Payload 4 takes a definitive step forward.

@payloadcms/richtext-slate is completely removed

The legacy Slate rich-text adapter is officially deleted in Payload 4. @payloadcms/richtext-lexical is now the sole official, built-in rich-text engine.

If your project still relies on Slate, you must migrate your data to Lexical before upgrading to v4:

bash
# Slate is not installable or supported on Payload 4
pnpm remove @payloadcms/richtext-slate
pnpm add @payloadcms/richtext-lexical@canary

Payload provides migration scripts and AST converters to transition existing Slate JSON documents to Lexical's node-based tree structure.

Lexical 0.50 upgrade and table stabilization

Payload 4 upgrades the underlying Lexical framework from version 0.41 to Lexical 0.50. Key enhancements include:

  • TableFeature graduation: EXPERIMENTAL_TableFeature is stabilized and renamed to TableFeature.
  • Stricter link nodes: Link node structures are validated against stricter schemas, preventing malformed URLs and broken target attributes.
  • Removal of deprecated converters: Legacy HTML/Markdown converter functions from early 3.x releases have been pruned in favor of the unified @payloadcms/richtext-lexical converter utilities.

6. List view performance and the Select API

Query efficiency in the admin panel has been overhauled to handle collections with millions of rows.

List View Select API enabled by default

In Payload 3, loading an admin list view fetched entire document objects from the database unless you explicitly configured admin.enableListViewSelectAPI: true. On collections with large rich-text fields or deep relations, opening the admin table caused significant server memory consumption and slow query times.

In Payload 4:

  • The Select API is active by default.
  • The config option admin.enableListViewSelectAPI has been removed.
  • Payload automatically crafts database queries that project only the columns currently visible in the editor's active table view.

forceSelect replaced by configurable select()

The static forceSelect: boolean property on field definitions has been deprecated. In its place, Payload 4 introduces a dynamic select() function, allowing field developers to programmatically determine whether a field should be included in database selections based on user permissions or context.


7. Developer tooling, schemas, and the official codemod

Payload 4 introduces first-class CLI commands and automated migration tooling to streamline upgrades.

The official migration codemod (npx @payloadcms/codemod)

To assist developers in transitioning from 3.x to 4.0, Payload provides an automated codemod:

bash
npx @payloadcms/codemod@latest

The codemod inspects your repository and automatically performs mechanical transformations:

  • Injects versions: false into collections that lacked explicit versioning, preserving existing database schema shapes.
  • Replaces deprecated request utilities (createLocalReq → createPayloadRequest).
  • Updates global component structures (admin.components.elements → admin.components.edit).
  • Migrates database adapter subpath imports to root exports.
  • Adjusts forceSelect instances to the new select signature.

Redesigned custom CLI commands (config.cli.commands)

In Payload 3, adding custom CLI commands relied on configuring config.bin, which lacked formal typing and argument parsing.

Payload 4 replaces config.bin with config.cli.commands, utilizing the defineCLICommand helper:

typescript
import { defineCLICommand } from 'payload';

export const syncSearchIndex = defineCLICommand({
  name: 'sync-search',
  description: 'Rebuild the vector search index across all articles',
  args: {
    dryRun: {
      type: 'boolean',
      short: 'd',
      description: 'Run without committing mutations',
    },
  },
  async handler({ payload, args }) {
    payload.logger.info(`Starting sync with dryRun=${args.dryRun}`);
    // Command implementation with full access to the local API
  },
});

Custom commands are executed directly via payload cli <command-name>, complete with auto-generated help menus and type-safe argument handling.

typescriptSchema becomes jsonSchema

On field configurations, typescriptSchema has been renamed to jsonSchema. Rather than merely generating static TypeScript types at build time, jsonSchema is preserved at runtime, enabling dynamic schema inspection by validation engines, REST clients, and AI agents.


8. MCP (Model Context Protocol) and AI agent workflows

AI-assisted engineering is a primary focal point of Payload 4. The @payloadcms/plugin-mcp package is published as a first-class v4 canary, tightly coupled with the core architecture.

The MCP boundary separates tool discovery from permission to execute a tool:

Diagram

Exposing a tool does not grant unrestricted data access. The v4 resolver identifies the caller through req.user; built-in tools apply their configured MCP access checks before execution.

Key MCP advancements in Payload 4 include:

  1. Opt-out tools by default: In 4.0, built-in collection and global tools are exposed automatically unless disabled. Review that exposure when upgrading: the default resolver authenticates a Payload user API key and built-in tools include permission checks; auth tools are separately opt-in. Tool exposure is not permission to bypass access control. See the official MCP migration notes.
  2. Runtime jsonSchema ingestion: Because fields expose standard JSON Schemas at runtime, MCP servers pass exact field types, enum values, and validation constraints directly to LLM tool-calling contexts, dramatically reducing AI hallucination.
  3. Payload Skills: The team maintains standardized agent skill definitions and evaluation suites, training AI assistants on idiomatic Payload 4 hooks, access control, and schema patterns.

9. Framework ecosystem and TanStack Start

Payload 3 tied itself intimately to Next.js and the React Server Components (RSC) App Router. While Next.js remains the primary tier-one platform, Payload 4 establishes an abstracted framework boundary.

@payloadcms/tanstack-start canary

Payload 4 introduces the @payloadcms/tanstack-start canary adapter. It is an experimental integration for evaluating Payload backend and admin rendering with:

  • TanStack Start
  • TanStack Router
  • Vite

The official Payload 4 preview describes a framework-adapter pattern and early TanStack support, rather than stable feature parity. Payload is moving framework-specific wiring out of its core. Teams seeking ultra-fast local Vite HMR, alternative server runtimes, or strict decoupling from Vercel's ecosystem can now leverage Payload with TanStack Start. For an evaluation of these two platforms, read our detailed TanStack Start vs Next.js comparison.

The adapter boundary lets framework-specific rendering and routing connect to the same Payload configuration:

Diagram

These are alternative framework integrations, not two runtimes required by one deployment. Next.js remains the established path; evaluate the TanStack canary independently before a production migration.

Minimum runtime baselines

Running Payload 4 requires modern infrastructure. The minimum supported runtime versions across the v4 branch are:

PrerequisiteMinimum VersionNotes
Node.js>= 24.15.0Required for modern native web crypto, streams, and ESM module resolution
Next.js (if using Next adapter)>= 16.2.6Aligns with Next.js Turbopack stability and current server component specifications
TypeScript>= 6.0.3Necessary for advanced type inference and schema type synthesis

For details on optimizing modern Next.js deployments, see our analysis on Payload CMS and Next.js compatibility.


The Big 4: Critical checklist for existing codebases

If you are planning an upgrade from Payload 3 to Payload 4, focus your engineering review on these four critical areas:

Treat these reviews as gates before generating a migration for an existing database:

Diagram

The codemod handles mechanical edits. Access decisions and database migration review still require a developer; inspect generated changes before applying them to a database.

  1. Audit Local API calls (overrideAccess: false): Search your codebase for all instances of payload.find, payload.create, payload.update, and payload.delete. If a query runs inside an internal task, migration script, or administrative server action without a user session, add overrideAccess: true. Otherwise, the query will run as public and fail or return empty datasets.

  2. Decide your versioning strategy (versions: true default): Do not run database migrations against Payload 4 without reviewing collection version configurations. If you do not want version tables created for all collections, either run npx @payloadcms/codemod to explicitly set versions: false or prepare your database capacity for new versioning tables.

  3. Refactor user typing in hooks and access rules: Replace legacy TypedUser imports with AuthenticatedUser. Check custom access control functions that inspected req.user properties to take advantage of typed _strategy and _sid.

  4. Prepare infrastructure for Node 24 and Next.js 16.2.6+: Ensure your Dockerfiles, CI/CD runners (GitHub Actions), and hosting environments (self-hosted Docker, Coolify, or VPS) are upgraded to Node.js 24 and support TypeScript 6.


Recommended upgrade path

When you are ready to evaluate the upgrade in a test branch:

  1. Branch cleanly: Create a dedicated feature/payload-4-migration branch.
  2. Upgrade dependencies: Point package.json to 4.0.0-canary.37 (or the latest canary release) across all @payloadcms/* packages.
  3. Run the codemod: Execute npx @payloadcms/codemod to apply baseline code transformations.
  4. Run TypeScript verification: Run npx tsc --noEmit to identify any residual type discrepancies resulting from the removal of DeepRequired or user type updates.
  5. Generate and inspect migrations: Run payload migrate:create against a local test database and inspect the generated SQL/migration files before applying them.

If you want an experienced team to audit your schemas, plugins, and custom admin extensions ahead of the stable v4 rollout, schedule a Payload CMS audit or engage an expert Payload CMS developer. For larger replatforming initiatives, explore our dedicated Payload CMS migration services.

Comments