The Payload Config

Payload is a config-based, code-first CMS and application framework. The Payload config is central to everything that Payload does. It scaffolds the data that Payload stores as well as maintains custom React components, hook logic, custom validations, and much more.

Also, because the Payload source code is fully written in TypeScript, its configs are strongly typed—meaning that even if you aren't using TypeScript, your IDE (such as VSCode) may still provide helpful information like type-ahead suggestions while you write your config.


admin *Base Payload admin configuration. Specify bundler*, custom components, control metadata, set the Admin user collection, and more. Required.
editor *Rich Text Editor which will be used by richText fields. Required.
db *Database Adapter which will be used by Payload. Read more here. Required.
serverURLA string used to define the absolute URL of your app including the protocol, for example No paths allowed, only protocol, domain and (optionally) port
collectionsAn array of all Collections that Payload will manage. To read more about how to define your collection configs, click here.
globalsAn array of all Globals that Payload will manage. For more on Globals and their configs, click here.
corsEither a whitelist array of URLS to allow CORS requests from, or a wildcard string ('*') to accept incoming requests from any domain.
localizationOpt-in and control how Payload handles the translation of your content into multiple locales. More
graphQLManage GraphQL-specific functionality here. Define your own queries and mutations, manage query complexity limits, and more.
cookiePrefixA string that will be prefixed to all cookies that Payload sets.
csrfA whitelist array of URLs to allow Payload cookies to be accepted from as a form of CSRF protection. More
defaultDepthIf a user does not specify depth while requesting a resource, this depth will be used. More
maxDepthThe maximum allowed depth to be permitted application-wide. This setting helps prevent against malicious queries. Defaults to 10.
indexSortableFieldsAutomatically index all sortable top-level fields in the database to improve sort performance and add database compatibility for Azure Cosmos and similar.
uploadBase Payload upload configuration. More.
routesControl the routing structure that Payload binds itself to. Specify admin, api, graphQL, and graphQLPlayground.
emailBase email settings to allow Payload to generate email such as Forgot Password requests and other requirements. More
expressExpress-specific middleware options such as compression and JSON parsing. More
debugEnable to expose more detailed error information.
telemetryDisable Payload telemetry by passing false. More
rateLimitControl IP-based rate limiting for all Payload resources. Used to prevent DDoS attacks and more.
hooksTap into Payload-wide hooks. More
pluginsAn array of Payload plugins. More
endpointsAn array of custom API endpoints added to the Payload router. More
customExtension point for adding custom data (e.g. for plugins)

* An asterisk denotes that a property is required.

Simple example

import { buildConfig } from 'payload/config'
import { mongooseAdapter } from '@payloadcms/db-mongodb'
import { postgresAdapter } from '@payloadcms/db-postgres' // beta
import { viteBundler } from '@payloadcms/bundler-vite'
import { webpackBundler } from '@payloadcms/bundler-webpack'
import { lexicalEditor } from '@payloadcms/richtext-lexical' // beta
import { slateEditor } from '@payloadcms/richtext-slate'
export default buildConfig({
admin: {
bundler: webpackBundler(), // or viteBundler()
db: mongooseAdapter({}) // or postgresAdapter({}),
editor: lexicalEditor({}) // or slateEditor({})
collections: [
slug: 'pages',
fields: [
name: 'title',
type: 'text',
required: true,
name: 'content',
type: 'richText',
required: true,
globals: [
slug: 'header',
fields: [
name: 'nav',
type: 'array',
fields: [
name: 'page',
type: 'relationship',
relationTo: 'pages',

Full example config

You can see a full example config in the Public Demo source code on GitHub.

Using environment variables in your config

We suggest using the dotenv package to handle environment variables alongside of Payload. All that's necessary to do is to require the package as high up in your application as possible (for example, at the top of your server.js file), and ensure that it can find an .env file that you create.

Add this line to the top of your server:

// ...
// the rest of your `server.js` file goes here

Note that if you rely on any environment variables in your config itself, you should also call dotenv() at the top of your config itself as well. There's no harm in calling it in both your server and your config itself!

Here is an example project structure w/ dotenv and an .env file:

---- .env
---- package.json
---- payload.config.js
---- server.js

Customizing & Automating Config Location Detection

Payload is designed to automatically locate your configuration file. By default, it will first look in the root of your current working directory for a file named payload.config.js or payload.config.ts if you're using TypeScript.

In development mode, if the configuration file is not found at the root, Payload will attempt to read your tsconfig.json, and search in the directory specified in compilerOptions.rootDir (typically "src").

In production mode, Payload will first attempt to find the config file in the output directory specified in compilerOptions.outDir of your tsconfig.json, then fallback to the source directory (compilerOptions.rootDir), and finally will check the 'dist' directory.

Please ensure your tsconfig.json is properly configured if you want Payload to accurately auto-detect your configuration file location. If tsconfig.json does not exist or doesn't specify rootDir or outDir, Payload will default to the current working directory.

Overriding the Config Location

In addition to the above automated detection, you can specify your own location for the Payload config file. This is done by using the environment variable PAYLOAD_CONFIG_PATH. The path you provide via this environment variable can either be absolute or relative to your current working directory. This can be useful in situations where your Payload config is not in a standard location, or you wish to switch between multiple configurations.

Example in package.json:

"scripts": {
"dev": "PAYLOAD_CONFIG_PATH=path/to/custom-config.js node server.js"

When PAYLOAD_CONFIG_PATH is set, Payload will use this path to load the configuration, bypassing all automated detection.

Developing within the Config

Payload comes with isomorphic-fetch installed which means that even in Node, you can use the fetch API just as you would within the browser. No need to import axios or similar, unless you want to!


You can import config types as follows:

import { Config } from 'payload/config'
// This is the type used for an incoming Payload config.
// Only the bare minimum properties are marked as required.
import { SanitizedConfig } from 'payload/config'
// This is the type used after an incoming Payload config is fully sanitized.
// Generally, this is only used internally by Payload.


Payload collects completely anonymous telemetry data about general usage. This data is super important to us and helps us accurately understand how we're growing and what we can do to build the software into everything that it can possibly be. The telemetry that we collect also help us demonstrate our growth in an accurate manner, which helps us as we seek investment to build and scale our team. If we can accurately demonstrate our growth, we can more effectively continue to support Payload as free and open-source software. To opt out of telemetry, you can pass telemetry: false within your Payload config.

For more information about what we track, take a look at our privacy policy.


Collection Configs