PayloadCMS from Scratch #1 - Create and configure project
Author
Adrian Maj
Date published

PayloadCMS is a modern, dynamically developing headless CMS dedicated to Next.js. Thanks to Payload, you can significantly speed up project creation by eliminating the need to repeatedly write the same boilerplate code. Its flexibility and simplicity make it perfect for both small websites and large applications requiring extensive admin panels.
In this post, I'll show you how to create your first "Hello World" in Payload and describe the individual elements of project configuration. After reading it, you'll have a solid foundation for further learning and working with this great tool.
Installation
For setting up Payload, we'll use the official npx
script, which simplifies the installation process.
- Creating a Project Directory
Create the directory in any location and open it in your preferred terminal.
š” Tip: Payload recommends pnpm, which I also recommend - you can find installation instructions here - Running the Installation Script
While in the directory, run the commandnpx create-payload-app@latest
- adding@latest
will always create the newest version. If you already have a folder created and don't want the wizard to create a new one inside, it's worth adding.
at the end of the command, then the project will be created in the current folder. - Choosing Settings
We choose the settings we're interested in, in my case it's the blank template and MongoDB database. As for the connection string, it can be changed later at any time in the.env
file. - Running the Application
According to the instructions displayed after confirmation, we launch our application. In our case, we're already in the folder where the project is located, so we can skip thecd
command. We start the development server with the commandpnpm dev
.
After a moment, Payload should be running locally and accessible at http://localhost:3000.

If at this stage you encounter problems with running the server, make sure that:
- Your database is working correctly.
- The .env file contains the correct connection string.
Project Structure
It's time to familiarize ourselves with what the wizard created for us. For quick access to Visual Studio Code, I recommend the command code .
in the terminal. After opening IDE, we see the following structure:
1š payload-template2āā š .next3āā š .vscode4āā š node_modules5āā š src6ā āā š app7ā ā āā š (frontend)8ā ā āā š (payload)9ā ā āā š my-route10ā āā š collections11ā ā āā š Media.ts12ā ā āā š Users.ts13ā ā āā š payload-types.ts14ā āā š payload.config.ts15āā š .env16āā š .env.example17āā š .gitignore18āā š .npmrc19āā š .prettierrc.json20āā š .yarnrc21āā š docker-compose.yml22āā š Dockerfile23āā š eslint.config.mjs24āā š next-env.d.ts25āā š next.config.mjs26āā š package.json27āā š pnpm-lock.yaml28āā š README.md29āā š tsconfig.json
Let's discuss the key elements that distinguish PayloadCMS from a standard Next.js project:
src/app/(frontend)
- folder where the Next.js application running under PayloadCMS is located.src/app/(payload)
- contains the Payload admin panel and all related files. This folder is created automatically and should not be modified.src/collections
- place for collections, which are the data structures that Payload is based on. Collections are defined in code, which eliminates the need for manual clicking ("click ops"), as is the case in competitive Strapi.payload-types.ts
- contains all generated types needed to work with collections. The file is updated automatically and should not be edited manually.payload-config.ts
- the main CMS configuration file. It defines, among others, database configuration, added collections, global settings, plugins, and many other options. Due to its extensiveness, it will probably get a separate article.
The remaining files are consistent with a standard Next.js project, so I won't discuss them here. If you haven't worked with Next.js before, it's worth familiarizing yourself with its documentation first.
Basic Configuration
Opening the payload-config.ts
file, we'll find the basic CMS configuration. It's worth analyzing each element carefully to later navigate this file freely and adapt it to your needs.
1// payload-config.ts23// storage-adapter-import-placeholder4import { mongooseAdapter } from '@payloadcms/db-mongodb'5import { payloadCloudPlugin } from '@payloadcms/payload-cloud'6import { lexicalEditor } from '@payloadcms/richtext-lexical'7import path from 'path'8import { buildConfig } from 'payload'9import { fileURLToPath } from 'url'10import sharp from 'sharp'1112import { Users } from './collections/Users'13import { Media } from './collections/Media'1415const filename = fileURLToPath(import.meta.url)16const dirname = path.dirname(filename)1718export default buildConfig({19 admin: {20 user: Users.slug,21 importMap: {22 baseDir: path.resolve(dirname),23 },24 },25 collections: [Users, Media],26 editor: lexicalEditor(),27 secret: process.env.PAYLOAD_SECRET || '',28 typescript: {29 outputFile: path.resolve(dirname, 'payload-types.ts'),30 },31 db: mongooseAdapter({32 url: process.env.DATABASE_URI || '',33 }),34 sharp,35 plugins: [36 payloadCloudPlugin(),37 // storage-adapter-placeholder38 ],39})
Storage Adapter
The first thing that catches the eye is a comment, or rather a placeholder for the storage adapter. It's worth configuring it right at the beginning because otherwise, all photos uploaded to the CMS will be saved locally in the project folder. This isn't the best solution, especially with a larger number of files.
Payload offers several adapters for file storage ā you can find more about this in the documentation. AWS S3 is definitely the most popular for self-hosted, and you can also find its configuration in the documentation.
š” Tip: The latest version of AWS S3 SDK introduced changes regarding checksums. To avoid errors, in the S3 configuration, set requestChecksumCalculation
and responseChecksumValidation
to "WHEN_REQUIRED"
.
Admin Panel
We now move to the configuration object, which in the default config starts with the admin key. It contains admin panel options, by default we have two positions configured:
user
- specifies the collection of users who have access to the admin panel. This allows us to separate application users from administrators by creating separate collections for them. You can provide a reference to the slug field from the collection object or directly enter its slug as a string, e.g., "users".importMap
- Here, we have configured the base directory (baseDir
) for custom components that can be used to personalize the admin panel. By default, it's thesrc
folder, the same one where the configuration file is located. At the beginning, it's worth sticking with this option.
Collections
Configuring collections in the configuration file is very simple. Just add a reference to the collection in the collections
array, and it will be automatically added to the admin panel.
After this operation, appropriate types for this collection should also be generated. However, if this doesn't happen, you can use the command pnpm generate:types
. This will manually force the generation of types from collections, fields, and global settings, which you'll learn more about in subsequent articles.
Other Options
The remaining options will be described briefly, as they are neither significant nor extensive enough to require a separate section.
editor
- here we set the default text editor forrichText
fields. By default, it's lexicalEditor, which we can customize and adapt to our needs. If we modify the editor, just provide a reference to our custom solution. Additionally, we can set different editors for individual fields, which gives us full flexibility. You can read more about therichText
editor in the docs.secret
- string used by Payload for encryption, password hashing, and other security-related operations. We usually leave this option default, as changing it can lead to problems with data access if our database isn't empty.typescript
- TypeScript settings for Payload. In most cases, we leave this field default, but if needed, we can customize the configuration, you can read more about it here.db
- Database adapter, set by default when creating the project, depending on the selected option. It's worth noting that this is an external package, so if we want to change the database type, we need to install the appropriate adapter. You can read more about databases in Payload in the docs.sharp
- If you work with Next.js, you probably know the sharp package, which is used for image optimization. Importing it into the Payload configuration allows for photo cropping, focal point selection, and automatic resizing in the admin panel. This makes images better adapted to different sizes and quickly loaded on the page.plugins
- As the name suggests, we add all plugins we want to use in our application to theplugins
array. Payload offers several official plugins, as well as countless community plugins that significantly extend its functionalities. The right choice of plugins will save time by eliminating the need to write your own implementations. You can find community plugins on GitHub by browsing the payload-plugin topic.
Summary
In this article, you learned how to easily install PayloadCMS, configure basic settings, and familiarize yourself with key elements of the project structure. You learned how to set up a storage adapter, customize the admin panel to your basic needs, and how to add collections. We also discussed important options in the payload-config.ts configuration file that allow for application personalization.
In the next article, we'll discuss next steps such as creating collections, user management, and configuring global settings. We'll also look at access control and permissions for different user groups.
If you want to continue learning and explore the topic of PayloadCMS, I encourage you to follow my blog,where I'll publish more articles on this topic. Additionally, on my social media profiles, I'll inform about new posts and updates related to PayloadCMS.