{"id":15162,"library":"payload","title":"Payload CMS","description":"Payload is an open-source, TypeScript-first headless CMS and application framework built on Node.js and React, frequently integrated with Next.js for full-stack applications. It is currently at version 3.83.0 and maintains an active release cadence, with multiple minor versions and bug fixes published monthly, indicating continuous and rapid development. A key differentiator is its code-first configuration approach, allowing developers to define collections, globals, and other configurations programmatically using TypeScript. This facilitates strong version control, type safety, and a developer-centric workflow, distinguishing it from CMS platforms that primarily rely on UI-driven configuration. Payload also provides a robust GraphQL API out-of-the-box, flexible authentication mechanisms, and a customizable, self-hosted admin panel, making it suitable for both content management and complex application backends.","status":"active","version":"3.83.0","language":"javascript","source_language":"en","source_url":"https://github.com/payloadcms/payload","tags":["javascript","admin panel","api","cms","content management","dashboard","framework","graphQL","headless","typescript"],"install":[{"cmd":"npm install payload","lang":"bash","label":"npm"},{"cmd":"yarn add payload","lang":"bash","label":"yarn"},{"cmd":"pnpm add payload","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for GraphQL API functionality, often needed by consumer applications interacting with Payload's GraphQL endpoint.","package":"graphql","optional":false}],"imports":[{"note":"Payload is primarily designed for ESM environments, especially with Next.js App Router in v3. While CommonJS might work in some server-side contexts, ESM is the idiomatic and recommended approach. The default export is the Payload instance.","wrong":"const payload = require('payload');","symbol":"payload","correct":"import payload from 'payload';"},{"note":"Configuration utilities like `buildConfig` are named exports from the `payload/config` module, not the main 'payload' entry point. Ensure correct path for schema definition.","wrong":"import buildConfig from 'payload/config';\nimport { buildConfig } from 'payload';","symbol":"buildConfig","correct":"import { buildConfig } from 'payload/config';"},{"note":"Type definitions for Payload schemas (e.g., `CollectionConfig`, `GlobalConfig`, `Field`) are available from the `payload/types` module for TypeScript users.","wrong":"import { CollectionConfig } from 'payload/config';","symbol":"CollectionConfig","correct":"import { CollectionConfig } from 'payload/types';"},{"note":"For dynamically generated types based on your specific Payload configuration (like `User`, `Post`, etc.), import them from `payload/generated-types`. This file is generated by Payload during development.","wrong":"import { User } from 'payload/dist/collections/Users/types'; // (example)\nimport { User } from 'payload/types';","symbol":"User","correct":"import type { User } from 'payload/generated-types';"}],"quickstart":{"code":"import { buildConfig } from 'payload/config';\nimport path from 'path';\n\nconst Users = {\n  slug: 'users',\n  auth: true,\n  admin: {\n    use=>: 'Email',\n  },\n  fields: [\n    {\n      name: 'name',\n      type: 'text',\n    },\n  ],\n};\n\nexport default buildConfig({\n  serverURL: process.env.PAYLOAD_PUBLIC_SERVER_URL ?? 'http://localhost:3000',\n  admin: {\n    user: 'users',\n  },\n  collections: [\n    Users,\n    {\n      slug: 'posts',\n      fields: [\n        {\n          name: 'title',\n          type: 'text',\n          required: true,\n        },\n        {\n          name: 'content',\n          type: 'richText',\n        },\n        {\n          name: 'author',\n          type: 'relationship',\n          relationTo: 'users',\n        },\n      ],\n    },\n  ],\n  typescript: {\n    outputFile: path.resolve(__dirname, 'payload-types.ts'),\n  },\n  graphQL: {\n    schemaOutputFile: path.resolve(__dirname, 'generated-schema.graphql'),\n  },\n});\n\n// To run this, you would typically have a server entry point like:\n// import payload from 'payload';\n// import express from 'express';\n// import { connect } from 'mongoose'; // or '@payloadcms/db-postgres'\n\n// const app = express();\n\n// async function start() {\n//   await connect(process.env.MONGODB_URI ?? 'mongodb://localhost/payload');\n\n//   await payload.init({\n//     secret: process.env.PAYLOAD_SECRET ?? 'super-secret-default-key',\n//     express: app,\n//     onInit: () => {\n//       payload.logger.info(`Payload Admin URL: ${payload.getAdminURL()}`);\n//     },\n//   });\n\n//   app.listen(3000, async () => {\n//     payload.logger.info('Express is listening on port 3000');\n//   });\n// }\n\n// start();","lang":"typescript","description":"This quickstart demonstrates a minimal Payload configuration with two collections (Users and Posts), including authentication, basic fields, and relationship fields. It shows the `buildConfig` utility and how to define schemas. It also outlines the typical server initialization process."},"warnings":[{"fix":"Refer to the official Payload v2 to v3 migration guide on the Payload CMS website. This will involve deleting `admin.bundler` from your config, uninstalling old bundler packages, and updating custom UI components. Data migration scripts may also need careful review and adjustment.","message":"Migrating from Payload v2 to v3 involves significant architectural changes. The Admin Panel was replatformed from a React Router SPA to the Next.js App Router, deprecating `admin.bundler` property and bundler packages like `@payloadcms/bundler-webpack` and `@payloadcms/bundler-vite`. Custom components and views require updating import paths and interfaces.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Adjust your application logic to ensure client-side code does not directly rely on `PAYLOAD_PUBLIC_` prefixed variables. Pass necessary public configuration through props to client components or utilize server components where appropriate.","message":"Environment variables prefixed with `PAYLOAD_PUBLIC` are no longer available on the client-side in v3. This change aligns with Next.js's server-side rendering capabilities and impacts how client-side code accesses public environment variables.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Always pin exact versions for all Payload-related packages in your `package.json` (e.g., `\"payload\": \"3.83.0\"` instead of `\"^3.83.0\"`). Delete `node_modules`, `package-lock.json` (or equivalent lock file), `.payload/`, and `.next/` directories, then run `npm install` (or `pnpm install`) to force a clean, consistent dependency resolution and rebuild.","message":"Dependency mismatches are a common source of cryptic runtime errors (e.g., 'Cannot destructure property 'config' of undefined') in Payload v3. All `payload`, `@payloadcms/*`, `react`, `react-dom`, and `next` packages must be installed at *exactly* the same version. Using caret (`^`) ranges can lead to inconsistencies.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Ensure your build environment has access to a database connection, or configure your Payload application to defer database connection until runtime, if possible. Monitor GitHub issues related to 'Build Fails Due to Missing Database Connection' for official fixes or workarounds.","message":"Payload builds (e.g., `npm run build`) can sometimes fail if an active database connection is not available at build time. This contradicts documentation and can be problematic in CI/CD environments where database access might be restricted during the build stage.","severity":"gotcha","affected_versions":">=3.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure all `payload` and `@payloadcms/*` packages, along with `react`, `react-dom`, and `next`, are pinned to identical versions in your `package.json`. Remove `node_modules`, `package-lock.json`, `.payload`, and `.next` directories, then reinstall dependencies.","cause":"This typically indicates a React context provider issue, often caused by inconsistent versions of `payload` or `@payloadcms/*` packages, or `react`/`react-dom` in your dependency tree, especially in monorepos.","error":"TypeError: Cannot destructure property 'config' of 'ue(...)' as it is undefined."},{"fix":"Verify your `MONGODB_URI` in `.env` is correct and properly formatted. Ensure special characters in passwords are URI-encoded. Check network access, firewall rules, and if your database server is active and accessible. Consider using a tool like MongoDB Compass to test the connection independently.","cause":"Payload failed to establish a connection with the database. This can be due to an incorrect `MONGODB_URI` environment variable, network issues (firewall, IP whitelisting), incorrect credentials (e.g., special characters in passwords needing URI encoding), or the database server not running.","error":"ERROR (payload): Error: cannot connect to MongoDB. Details: URI does not have hostname, domain name and tld"},{"fix":"Review your Payload configuration for `CORS`, `CSRF`, and `cookie` settings. Explicitly whitelist your frontend domain in `CORS` rather than using `*`. Check browser developer tools for cookie rejection warnings to diagnose misconfigured cookie domain or security flags. Verify your access control functions are correctly implemented.","cause":"This error occurs when an authentication cookie is not being set or accepted correctly, or when access control functions deny the request.","error":"Unauthorized, you must be logged in to make this request"},{"fix":"Explicitly list allowed origins in your `cors` array (e.g., `cors: ['http://localhost:3000', 'http://localhost:8080']`). Ensure your `serverURL` in `payload.config.ts` accurately reflects the URL where your Payload API is accessible. For specific HTTP methods, ensure they are correctly cased (e.g., 'PATCH' not 'patch').","cause":"Despite setting `cors: '*'` in `payload.config.ts`, browsers may still block requests due to preflight checks or specific browser security policies. This is often an issue when the serverURL is not correctly configured for the API.","error":"CORS error when accessing with other ports, even with cors: '*'"}],"ecosystem":"npm"}