139 lines
4.1 KiB
Markdown
139 lines
4.1 KiB
Markdown
---
|
||
title: "Payload CMS — Installation & Setup"
|
||
aliases: [payload-cms, payloadcms-install, payload-nextjs]
|
||
tags: [payload-cms, nextjs, cms, headless, typescript]
|
||
sources: [raw/Installation Documentation.md]
|
||
created: 2026-05-15
|
||
updated: 2026-05-15
|
||
---
|
||
|
||
## Payload CMS — Installation & Setup
|
||
|
||
[Payload CMS](https://payloadcms.com) is a TypeScript-first headless CMS that runs **inside** a Next.js app (App Router). No separate backend process — Payload lives in your `/app/(payload)/` route group.
|
||
|
||
## Requirements
|
||
|
||
| Requirement | Version |
|
||
|-------------|---------|
|
||
| Node.js | 20.9.0+ |
|
||
| Next.js | `15.2.9–15.2.x` / `15.3.9–15.3.x` / `15.4.11–15.4.x` / `16.2.2+` |
|
||
| Package manager | pnpm (preferred), npm, yarn 2+ (yarn 1.x **not supported**) |
|
||
| Database | MongoDB, Postgres, or SQLite |
|
||
|
||
> **Not all Next.js 15/16 patch releases are compatible** — use only the version ranges above.
|
||
|
||
## Quickstart (new project)
|
||
|
||
```bash
|
||
npx create-payload-app
|
||
```
|
||
|
||
Follow the prompts — you get a working Payload app in a new folder.
|
||
|
||
## Add to Existing Next.js App
|
||
|
||
### 1. Install packages
|
||
|
||
```bash
|
||
pnpm i payload @payloadcms/next
|
||
|
||
# Optional but common:
|
||
pnpm i @payloadcms/richtext-lexical # Rich text editor
|
||
pnpm i sharp # Image resize/crop/focal point
|
||
pnpm i graphql # Only if using GraphQL API
|
||
```
|
||
|
||
**Database adapter — pick one:**
|
||
|
||
```bash
|
||
pnpm i @payloadcms/db-mongodb # MongoDB
|
||
pnpm i @payloadcms/db-postgres # Postgres
|
||
pnpm i @payloadcms/db-sqlite # SQLite
|
||
```
|
||
|
||
> npm users: `npm i --legacy-peer-deps`
|
||
|
||
### 2. Copy Payload files into `/app`
|
||
|
||
Copy the `(payload)` route group from [Blank Template](https://github.com/payloadcms/payload/tree/3.x/templates/blank/src/app/%28payload%29):
|
||
|
||
```
|
||
app/
|
||
├── (payload)/ ← Payload admin + API routes (never edit these)
|
||
└── (my-app)/ ← Your existing frontend (rename freely)
|
||
```
|
||
|
||
Move existing frontend files into a new route group (e.g. `(frontend)`). Payload files import from `@payloadcms/next` — set once, never revisited.
|
||
|
||
### 3. Wrap Next.js config with `withPayload`
|
||
|
||
```js
|
||
// next.config.mjs ← must be ESM (.mjs or "type":"module" in package.json)
|
||
import { withPayload } from '@payloadcms/next/withPayload'
|
||
|
||
const nextConfig = {
|
||
// your config
|
||
}
|
||
|
||
export default withPayload(nextConfig)
|
||
```
|
||
|
||
> Payload is fully ESM — `require()` won't work. Use `.mjs` extension or set `"type": "module"`.
|
||
|
||
### 4. Create `payload.config.ts`
|
||
|
||
```ts
|
||
import sharp from 'sharp'
|
||
import { lexicalEditor } from '@payloadcms/richtext-lexical'
|
||
import { mongooseAdapter } from '@payloadcms/db-mongodb'
|
||
import { buildConfig } from 'payload'
|
||
|
||
export default buildConfig({
|
||
editor: lexicalEditor(),
|
||
collections: [],
|
||
secret: process.env.PAYLOAD_SECRET || '',
|
||
db: mongooseAdapter({
|
||
url: process.env.DATABASE_URL || '',
|
||
}),
|
||
sharp,
|
||
})
|
||
```
|
||
|
||
Register the config path in `tsconfig.json`:
|
||
|
||
```json
|
||
{
|
||
"compilerOptions": {
|
||
"paths": {
|
||
"@payload-config": ["./payload.config.ts"]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5. Start & create first user
|
||
|
||
```bash
|
||
pnpm dev
|
||
# → http://localhost:3000/admin
|
||
```
|
||
|
||
## Key Takeaways
|
||
|
||
- Payload runs **inside Next.js** — no separate server; admin panel at `/admin`
|
||
- Only specific Next.js patch versions are compatible — check the list before upgrading
|
||
- `(payload)` route group files are **never edited** — they're boilerplate from the template
|
||
- `withPayload` in `next.config` must be ESM — use `.mjs` or `"type":"module"`
|
||
- `PAYLOAD_SECRET` must be a strong random string (used to sign tokens)
|
||
- `sharp` is optional — only needed for image manipulation in Upload collections
|
||
- `@payloadcms/richtext-lexical` is optional — only needed if using Rich Text fields
|
||
|
||
## Related
|
||
|
||
- [[wiki/tech-patterns/nextjs-fastapi-fullstack|Next.js + FastAPI Fullstack]] — alternative when you need a separate Python backend
|
||
- [[wiki/tech-patterns/react-vite-typescript|React + Vite + TypeScript]] — SPA alternative without SSR/CMS
|
||
- [[wiki/tech-patterns/azure-ad-msal-auth|Azure AD / MSAL Auth]] — if Payload needs SSO instead of built-in auth
|
||
|
||
## Sources
|
||
|
||
- `raw/Installation Documentation.md` — clipped from https://payloadcms.com/docs/getting-started/installation
|